From 1ebc5474f200767f3339e15620344fa45bd43ad3 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Fri, 27 Jun 2025 22:46:39 +0200 Subject: [PATCH] Drop ERC --- doc/misc/Makefile.in | 4 +- doc/misc/erc.texi | 2311 ----- etc/ERC-NEWS | 2551 ------ lisp/desktop.el | 1 - lisp/erc/ChangeLog.1 | 11726 ------------------------ lisp/erc/ChangeLog.2 | 780 -- lisp/erc/erc-autoaway.el | 278 - lisp/erc/erc-backend.el | 2924 ------ lisp/erc/erc-button.el | 885 -- lisp/erc/erc-capab.el | 210 - lisp/erc/erc-common.el | 665 -- lisp/erc/erc-compat.el | 470 - lisp/erc/erc-dcc.el | 1285 --- lisp/erc/erc-desktop-notifications.el | 123 - lisp/erc/erc-ezbounce.el | 178 - lisp/erc/erc-fill.el | 932 -- lisp/erc/erc-goodies.el | 1161 --- lisp/erc/erc-ibuffer.el | 188 - lisp/erc/erc-identd.el | 119 - lisp/erc/erc-imenu.el | 172 - lisp/erc/erc-join.el | 256 - lisp/erc/erc-lang.el | 211 - lisp/erc/erc-list.el | 230 - lisp/erc/erc-log.el | 466 - lisp/erc/erc-match.el | 715 -- lisp/erc/erc-menu.el | 135 - lisp/erc/erc-netsplit.el | 214 - lisp/erc/erc-networks.el | 1667 ---- lisp/erc/erc-nicks.el | 809 -- lisp/erc/erc-notify.el | 469 - lisp/erc/erc-page.el | 114 - lisp/erc/erc-pcomplete.el | 298 - lisp/erc/erc-replace.el | 93 - lisp/erc/erc-ring.el | 150 - lisp/erc/erc-sasl.el | 440 - lisp/erc/erc-services.el | 665 -- lisp/erc/erc-sound.el | 150 - lisp/erc/erc-speedbar.el | 685 -- lisp/erc/erc-spelling.el | 143 - lisp/erc/erc-stamp.el | 1187 --- lisp/erc/erc-status-sidebar.el | 612 -- lisp/erc/erc-track.el | 1262 --- lisp/erc/erc-truncate.el | 183 - lisp/erc/erc-xdcc.el | 137 - lisp/erc/erc.el | 9908 -------------------- lisp/info.el | 2 +- lisp/org/ol-info.el | 2 +- lisp/org/ol-irc.el | 272 - lisp/org/org.el | 1 - lisp/progmodes/bug-reference.el | 21 +- lisp/url/url-irc.el | 4 - 51 files changed, 7 insertions(+), 48457 deletions(-) delete mode 100644 doc/misc/erc.texi delete mode 100644 etc/ERC-NEWS delete mode 100644 lisp/erc/ChangeLog.1 delete mode 100644 lisp/erc/ChangeLog.2 delete mode 100644 lisp/erc/erc-autoaway.el delete mode 100644 lisp/erc/erc-backend.el delete mode 100644 lisp/erc/erc-button.el delete mode 100644 lisp/erc/erc-capab.el delete mode 100644 lisp/erc/erc-common.el delete mode 100644 lisp/erc/erc-compat.el delete mode 100644 lisp/erc/erc-dcc.el delete mode 100644 lisp/erc/erc-desktop-notifications.el delete mode 100644 lisp/erc/erc-ezbounce.el delete mode 100644 lisp/erc/erc-fill.el delete mode 100644 lisp/erc/erc-goodies.el delete mode 100644 lisp/erc/erc-ibuffer.el delete mode 100644 lisp/erc/erc-identd.el delete mode 100644 lisp/erc/erc-imenu.el delete mode 100644 lisp/erc/erc-join.el delete mode 100644 lisp/erc/erc-lang.el delete mode 100644 lisp/erc/erc-list.el delete mode 100644 lisp/erc/erc-log.el delete mode 100644 lisp/erc/erc-match.el delete mode 100644 lisp/erc/erc-menu.el delete mode 100644 lisp/erc/erc-netsplit.el delete mode 100644 lisp/erc/erc-networks.el delete mode 100644 lisp/erc/erc-nicks.el delete mode 100644 lisp/erc/erc-notify.el delete mode 100644 lisp/erc/erc-page.el delete mode 100644 lisp/erc/erc-pcomplete.el delete mode 100644 lisp/erc/erc-replace.el delete mode 100644 lisp/erc/erc-ring.el delete mode 100644 lisp/erc/erc-sasl.el delete mode 100644 lisp/erc/erc-services.el delete mode 100644 lisp/erc/erc-sound.el delete mode 100644 lisp/erc/erc-speedbar.el delete mode 100644 lisp/erc/erc-spelling.el delete mode 100644 lisp/erc/erc-stamp.el delete mode 100644 lisp/erc/erc-status-sidebar.el delete mode 100644 lisp/erc/erc-track.el delete mode 100644 lisp/erc/erc-truncate.el delete mode 100644 lisp/erc/erc-xdcc.el delete mode 100644 lisp/erc/erc.el delete mode 100644 lisp/org/ol-irc.el diff --git a/doc/misc/Makefile.in b/doc/misc/Makefile.in index 0eff0269a73..12b4aa8de11 100644 --- a/doc/misc/Makefile.in +++ b/doc/misc/Makefile.in @@ -67,7 +67,7 @@ DOCMISC_W32 = @DOCMISC_W32@ ## Info files to build and install on all platforms. INFO_COMMON = auth autotype calc ccmode cl dbus dired-x \ ediff efaq eglot eieio emacs-gnutls \ - emacs-mime epa erc ert eshell eudc eww flymake forms gnus \ + emacs-mime epa ert eshell eudc eww flymake forms gnus \ htmlfontify info.info mairix-el message \ modus-themes newsticker nxml-mode octave-mode org pcl-cvs pgg \ rcirc remember sasl sc ses sieve smtpmail \ @@ -184,7 +184,7 @@ $(foreach ifile,$(filter-out info.info,$(INFO_TARGETS)),$(eval $(call info_templ ## Extra dependencies. ## FIXME Updating this list manually is unreliable. -need_emacsver = calc cl dired-x efaq efaq-w32 erc forms \ +need_emacsver = calc cl dired-x efaq efaq-w32 forms \ newsticker remember use-package woman need_emacsver_prefix = $(addprefix ${buildinfodir}/,${need_emacsver}) diff --git a/doc/misc/erc.texi b/doc/misc/erc.texi deleted file mode 100644 index 613df49883b..00000000000 --- a/doc/misc/erc.texi +++ /dev/null @@ -1,2311 +0,0 @@ -\input texinfo -@c %**start of header -@setfilename ../../info/erc.info -@settitle ERC Manual -@set ERCVER 5.6.1 -@set ERCDIST as distributed with Emacs @value{EMACSVER} -@include docstyle.texi -@syncodeindex fn cp -@include emacsver.texi -@c %**end of header - -@copying -This manual is for ERC @value{ERCVER} @value{ERCDIST}. - -Copyright @copyright{} 2005--2025 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.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, with the Front-Cover Texts being ``A GNU Manual,'' -and with the Back-Cover Texts as in (a) below. A copy of the license -is included in the section entitled ``GNU Free Documentation License''. - -(a) The FSF's Back-Cover Text is: ``You have the freedom to copy and -modify this GNU manual.'' - -All Emacs Lisp code contained in this document may be used, distributed, -and modified without restriction. -@end quotation -@end copying - -@dircategory Emacs network features -@direntry -* ERC: (erc). Powerful and extensible IRC client for Emacs. -@end direntry - -@titlepage -@title ERC manual -@subtitle a full-featured IRC client -@subtitle for Emacs - -@c The following two commands -@c start the copyright page. -@page -@vskip 0pt plus 1filll -@insertcopying -@end titlepage - -@contents - -@ifnottex -@node Top -@top ERC - -@insertcopying -@end ifnottex - -@menu -* Introduction:: What is 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. -* GNU Free Documentation License:: The license for this documentation. -* Concept Index:: Search for terms. - -@detailmenu - --- The Detailed Node Listing --- - -Getting Started - -* Sample Session:: Example of connecting to the @samp{#emacs} channel -* Special Features:: Differences from standalone IRC clients - -Advanced Usage - -* Connecting:: Ways of connecting to an IRC server. -* SASL:: Authenticating via SASL. -* Sample Configuration:: An example configuration file. -* Integrations:: Integrations available for ERC. -* Options:: Options that are available for ERC. - -@end detailmenu -@end menu - -@node Introduction -@chapter Introduction - -ERC is a powerful, modular, and extensible IRC client for Emacs. -It has been included in Emacs since 2006 (@pxref{History}) and is also -available on GNU ELPA. - -IRC is short for Internet Relay Chat. When using IRC, you can -communicate with other users on the same IRC network. There are many -different networks---if you search for ``IRC networks'' in your -favorite search engine, you will find up-to-date lists of IRC networks -catering to various interests and topics. - -To use IRC, you need an IRC client such as ERC. Using the client, you -connect to an IRC server. Once you've done that, you will have access -to all available channels on that server's network. A channel is -basically a chat room, and what you type in a channel will be shown to -all other users in that channel. You can be in several channels at -the same time---ERC will show each channel in its own buffer. - -IRC channel names always begin with a @samp{#} character. For -example, the Emacs channel on Libera.Chat is @samp{#emacs}, and the -ERC channel is @samp{#erc}. Do not confuse them with the hashtags -used on many social media platforms. - -You can also send private messages to other IRC users on the same -network, even if they are not in the same channels as you. - -ERC 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 Getting Started -@chapter Getting Started -@cindex settings - -The command @kbd{M-x erc} will start ERC and prompt for the server to -connect to. If you're unsure of which server or network to connect -to, we suggest starting with ``irc.libera.chat''. There you will find -the @samp{#emacs} channels where you can chat with other Emacs users, -and if you're having trouble with ERC, you can join the @samp{#erc} -channel and ask for help there. - -At some point in your ERC journey, you'll inevitably want to change -how the client looks and behaves. As with other Emacs applications, -the typical place to store your settings is your @file{init.el}. If -you would rather use the Customize interface, a good place to start is -by running @kbd{M-x customize-group @key{RET} erc @key{RET}}. In -particular, ERC comes with lots of modules that may be enabled or -disabled; to select which ones you want, do @kbd{M-x -customize-variable @key{RET} erc-modules @key{RET}}. - -@menu -* Sample Session:: Example of connecting to the #emacs channel -* Special Features:: Differences from standalone IRC clients -@end menu - -@node Sample Session -@section Sample Session - -This example ERC session describes how to connect to the @samp{#emacs} -channel on Libera.Chat. Also worth checking out is Libera's own -introductory guide to IRC, @uref{https://libera.chat/guides/basics}, -which presents a more comprehensive overview without instructions -specific to ERC. - -@itemize @bullet - -@item Connect to Libera.Chat - -Run @kbd{M-x erc @key{RET}}. Use @samp{irc.libera.chat} for the -server and @samp{6667} for the port. Choose a nickname, and hit -@key{y} when asked if you'd prefer to connect over @acronym{TLS}. - -@item Get used to the interface - -Switch to the @file{Libera.Chat} buffer if you're not already there. -ERC calls this a @dfn{server buffer}, and it must exist for the -duration of the session. You will likely see some messages about -``ident'', authentication, and the like, followed by information -describing the current server and the network. - -@item Join the #emacs channel - -In the server buffer, type @kbd{/join #emacs @key{RET}} at the prompt. -ERC will create a new buffer called @file{#emacs}. If you've already -configured ERC, you may need to switch to it manually. Once there, -you will see the channel's ``topic'' in the buffer's header line -(@pxref{Header Lines,,,elisp,}) and a list of people currently in the -channel. If you can't see the full topic, mouse over it or type -@kbd{/topic @key{RET}} at the prompt. - -@item Register your nickname with Libera.Chat - -In order to access essential network features, like speaking in -certain channels and participating in private conversations, you'll -likely have to ``register'' your nickname. To do so, switch to the -@file{Libera.Chat} buffer and type @kbd{/msg NickServ register -@samp{} @samp{} @key{RET}}, replacing -@samp{} and @samp{} with your desired account -password and contact email (both sans quotes). The server should tell -you that the operation was successful. See the official Libera.Chat -docs if you encounter problems. - -In addition to creating an account, this process also -``authenticates'' you to the network's ``account services'' system for -the duration of the session. In other words, you're now logged in. -However, when you connect in the future, you'll need to authenticate -again by providing the same credentials somehow. When you're finished -with this walk through, see ``Next Steps'', below, to learn some ways -to do that. - -@item Talk to people in the channel - -Switch back to the @file{#emacs} buffer and type a message at the -prompt, hitting @kbd{RET} once satisfied. Everyone in the channel -will now see your message. - -@item Open a query buffer to talk to someone - -If you want to talk with someone in private, type @kbd{/query -@samp{} @key{RET}}, replacing @samp{} with the their -nickname. As before, with the server buffer, if this new @dfn{query -buffer} doesn't appear in the current window, you may have to switch -to it. Regardless, its name should match @samp{}. Once there, -type something at the prompt and hit @kbd{RET}, and the other party -will see it. - -Keep in mind that if either party isn't authenticated, you may not be -able to converse at all. Also, depending on the network, certain -social conventions may apply to the practice of direct messaging. As -a general rule, queries should usually be reserved for personal -matters rather than technical help, which can often benefit (and -benefit @emph{from}) a larger audience. - -@item Next steps - -Try joining another channel, such as @samp{#erc}, where ERC users and -developers hang out (@pxref{Official IRC channels} for more on the -history of @samp{#emacs}). For ideas on various options to customize, -@pxref{Sample Configuration}. To learn how ERC can authenticate you -to the network automatically whenever you connect, @pxref{SASL}. As -always, if you encounter problems, @pxref{Getting Help and Reporting -Bugs}. - -@end itemize - -@node Special Features -@section Special Features - -ERC has some features that distinguish it from some IRC clients. - -@itemize @bullet - -@item multiple channels and multiple servers - -Every channel is put in a separate buffer. Several IRC servers may be -connected to at the same time. - -@cindex query buffers -@item private message separation - -Private conversations are treated as channels, and are put into separate -buffers in Emacs. We call these ``query buffers''. - -@item highlighting - -Some occurrences of words can be highlighted, which makes it easier to -track different kinds of conversations. - -@item notification - -ERC can notify you that certain users are online. - -@item channel tracking - -Channels can be hidden and conversation continue in the background. You -are notified when something is said in such a channel that is not -currently visible. This makes it easy to get Real Work done while still -maintaining an IRC presence. - -@item nick completion - -ERC can complete words upon hitting @kbd{TAB}, which eases the writing -of nicknames in messages. - -@cindex history ring -@item history - -Past actions are kept in history rings for future use. To navigate a -history ring, hit @kbd{M-p} to go backwards and @kbd{M-n} to go -forwards. - -@item multiple languages - -Different channels and servers may have different language encodings. - -multiple languages. Please contact the Emacs developers -if you are interested in helping with the -translation effort. - -@item user scripting - -Users can load scripts (e.g., auto greeting scripts) when ERC starts up. - -It is also possible to make custom IRC commands, if you know a little -Emacs Lisp. Just make an Emacs Lisp function and call it -@code{erc-cmd-NEWCOMMAND}, where @code{NEWCOMMAND} is the name of the -new command in capital letters. - -@item auto reconnect - -If the connection goes away at some point, ERC will try to reconnect -automatically. If it fails to reconnect, and you want to try to -manually reestablish the connection at some later point, switch to an -ERC buffer and run the @code{/RECONNECT} command. - -@end itemize - - -@node Keystroke Summary -@chapter Keys Used in ERC -@cindex keystrokes - -This is a summary of keystrokes available in every ERC buffer. - -@table @kbd - -@item C-a or (@code{erc-bol}) -Go to beginning of line or end of prompt. - -@item @key{RET} (@code{erc-send-current-line}) -Send the current line - -@item @key{TAB} (@code{completion-at-point} or @code{erc-button-next}) -If at prompt, complete the current word. -Otherwise, move to the next link or button. - -@item M-@key{TAB} (@code{ispell-complete-word}) -Complete the given word, using ispell. - -@item C-c C-a (@code{erc-bol}) -Go to beginning of line or end of prompt. - -@item C-c C-b (@code{erc-switch-to-buffer}) -Use @code{read-buffer} to prompt for a ERC buffer to switch to. - -@item C-c C-c (@code{erc-toggle-interpret-controls}) -Toggle interpretation of control sequences in messages. - -@item C-c C-d (@code{erc-input-action}) -Interactively input a user action and send it to IRC. - -@item C-c C-e (@code{erc-toggle-ctcp-autoresponse}) -Toggle automatic CTCP replies (like VERSION and PING). - -@item C-c C-f (@code{erc-toggle-flood-control}) -Toggle use of flood control on sent messages. - -@item C-c @key{TAB} (@code{erc-invite-only-mode}) -Turn on the invite only mode (+i) for the current channel. - -@item C-c C-j (@code{erc-join-channel}) -Join channel. If point is at the beginning of a channel name, use that -as default. - -@item C-c C-k (@code{erc-go-to-log-matches-buffer}) -Interactively open an erc-log-matches buffer - -@item C-c C-l (@code{erc-save-buffer-in-logs}) -Append buffer contents to the log file, if logging is enabled. - -@item C-c C-n (@code{erc-channel-names}) -Run "/names #channel" in the current channel. - -@item C-c C-o (@code{erc-get-channel-mode-from-keypress}) -Read a key sequence and call the corresponding channel mode function. -After doing @kbd{C-c C-o}, type in a channel mode letter. - -@kbd{C-g} means quit. -@kbd{RET} lets you type more than one mode at a time. -If @kbd{l} is pressed, @code{erc-set-channel-limit} gets called. -If @kbd{k} is pressed, @code{erc-set-channel-key} gets called. -Anything else will be sent to @code{erc-toggle-channel-mode}. - -@item C-c C-p (@code{erc-part-from-channel}) -Part from the current channel and prompt for a reason. - -@item C-c C-q (@code{erc-quit-server}) -Disconnect from current server after prompting for reason. - -@item C-c C-r (@code{erc-remove-text-properties-region}) -Clears the region (start,end) in object from all colors, etc. - -@item C-c C-t (@code{erc-set-topic}) -Prompt for a topic for the current channel. - -@item C-c C-u (@code{erc-kill-input}) -Kill current input line using @code{erc-bol} followed by @code{kill-line}. - -@end table - - -@node Modules -@chapter Modules -@cindex modules - -One way to add functionality to ERC is to customize which of its many -modules are loaded. - -You can do this by typing @kbd{C-h v erc-modules @key{RET}} and clicking -@samp{customize} near the bottom of the resulting help buffer, where it -says ``You can @emph{customize} this variable.'' When -removing a module outside of Customize, you may wish to ensure it's -disabled by invoking its associated minor-mode toggle with a -nonpositive prefix argument, for example, @kbd{C-u - M-x -erc-spelling-mode @key{RET}}. Additionally, if you plan on loading -third-party modules that perform atypical setup on activation, you may -need to arrange for calling @code{erc-update-modules} in your init -file. Examples of such setup might include registering an -@code{erc-before-connect} hook, advising @code{erc-open}, and -modifying @code{erc-modules} itself. On Emacs 29 and greater, you can -also run @code{erc-update-modules} indirectly, via @code{(setopt -erc-modules erc-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, bufbar -@item bufbar -List buffers belonging to a connection in a side window; part of -Custom group @code{erc-status-sidebar} - -@cindex modules, button -@item button -Buttonize URLs, nicknames, and other text - -@cindex modules, capab-identify -@item capab-identify -Mark unidentified users on freenode and other servers supporting CAPAB. - -@cindex modules, command-indicator -@item command-indicator (local) -Echo command lines for ``slash commands'', like @kbd{/JOIN #erc} and -@kbd{/HELP join} - -@cindex modules, completion -@cindex modules, pcomplete -@item completion (aka pcomplete) -Complete nicknames and commands (programmable) - -@cindex modules, fill -@item fill -Wrap long lines - -@cindex modules, identd -@item identd -Launch an identd server on port 8113 - -@cindex modules, irccontrols -@item irccontrols -Highlight or remove IRC control characters - -@cindex modules, keep-place -@item keep-place -Remember your position in buffers - -@cindex modules, log -@item log -Save buffers in logs - -@cindex modules, match -@item match -Highlight pals, fools, and other keywords - -@cindex modules, menu -@item menu -Display a menu in ERC buffers - -@cindex modules, netsplit -@item netsplit -Detect netsplits - -@cindex modules, nicks -@item nicks (local) -Automatically colorize nicks - -@cindex modules, nickbar -@item nickbar -List participating nicks for the current target buffer in a side -window; part of Custom group @code{erc-speedbar} - -@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, notifications -@item notifications -Send you a notification when you get a private message, -or your nickname is mentioned - -@cindex modules, page -@item page -Process CTCP PAGE requests from IRC - -@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, sasl -@item sasl (local) -Enable SASL authentication - -@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, spelling -@item spelling -Check spelling of messages - -@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 - -@anchor{Auxiliary Modules} -@subheading Auxiliary Modules -@cindex auxiliary modules - -For various reasons, the following modules aren't currently listed in -the Custom interface for @code{erc-modules}, but feel free to add them -explicitly. They may be managed by another module or just deemed too -niche or experimental. - -@table @code - -@cindex modules, fill-wrap -@item fill-wrap (local) -Wrap long lines using @code{visual-line-mode} - -@cindex modules, keep-place-indicator -@item keep-place-indicator (local) -Remember your place in buffers with a visible reminder; activated -interactively or via something like @code{erc-join-hook} - -@cindex modules, querypoll -@item querypoll (local) -Update query participant data by continually polling the server - -@cindex modules, services-regain -@item services-regain (local) -Automatically ask NickServ to reclaim your nick when reconnecting; -experimental as of ERC 5.6 - -@end table - -@anchor{Required Modules} -@subheading Required Modules -@cindex required modules - -Note that some modules are essential to core IRC operations and thus -not listed above. You can nevertheless still remove these, but doing -so demands special precautions to avoid degrading the user experience. -At present, the only such module is @code{networks}, whose library ERC -always loads anyway. - -@anchor{Local Modules} -@subheading Local Modules -@cindex local modules - -@c Earlier language in code comments, commit messages, and tracker -@c discussions used to describe a local module as being "active" in a -@c buffer if it had a local binding but "disabled" if that binding's -@c value was nil. For better or worse, ERC has since abandoned that -@c distinction and now considers "active" to be synonymous with -@c "enabled". - -All modules operate as minor modes under the hood, and newer ones are -mostly defined as buffer-local. These so-called @dfn{local modules} are -a work in progress, and their behavior and interface are subject to -change. As of ERC 5.6, the only practical differences are as follows: - -@enumerate -@item -@dfn{Mode variables}, a.k.a. @dfn{control variables}, like -@code{erc-sasl-mode}, retain their values across IRC sessions. -@item -Removing a local module from @code{erc-modules} via Customize not only -disables its mode but also kills its mode variable in all ERC buffers. -@item -@dfn{Mode commands}, like @code{erc-sasl-mode} and its one-way variants -@code{erc-sasl-enable} and @code{erc-sasl-disable}, behave differently -than their global counterparts. -@end enumerate - -To detect whether a module is local, examine its mode variable. For -example, if you run @kbd{C-h v erc-sasl-mode @key{RET}}, you'll notice -it says ``Automatically becomes buffer-local when set''. You can do the -same in Lisp code with @code{(local-variable-if-set-p 'erc-sasl-mode)}. - -In an ERC buffer, a local module is either enabled or disabled if its -mode variable has a local binding. This @dfn{activation state} may -contradict a module's presence in @code{erc-modules}, namely, in buffers -where it isn't applicable or has otherwise been disabled. In fact, a -local module's membership in @code{erc-modules} does nothing more than -guarantee - -@enumerate -@item -its setup code runs in @emph{new} buffers -@item -its mode variable has a local binding in all affected buffers -@end enumerate - -In keeping with this, all built-in local modules disable themselves in -nonapplicable buffers rather than remain no-ops. Some also take strides -to enable themselves elsewhere when needed or at least emit a helpful -error. For example, the @samp{nicks} module does both in server -buffers, where it shares resources among the target buffers it primarily -services. ERC expects third-party local modules to mimic this pattern -and to document what buffer types they operate in: server, query, or -channel. (In the case of @samp{nicks}, it would be all three: it's -@dfn{session-local}.) - -In ERC, you can think of an IRC session as a group of buffers sharing -the same connection to a server. After a connection ends, this -association endures so that ERC can revive the session when -reconnecting. As it does with connection parameters, ERC therefore -persists a local module's activation state through reconnections, -reenabling modules that were previously active while ensuring others are -disabled. A couple related things to note here are - -@enumerate -@item -each module must manage its own application data and restore or reset -its environment accordingly -@item -session persistence is less predictable if a user changes the makeup of -@code{erc-modules} between sessions -@end enumerate - -When it comes to a local module's various activation commands, the -primary mode command, like @code{erc-sasl-mode}, for example, only -affects the current buffer, but its unidirectional cousins, like -@code{erc-sasl-enable} and @code{erc-sasl-disable}, operate on all -buffers belonging to their connection (when called interactively). And -unlike global toggles, none of these ever mutates @code{erc-modules}. - - -@c FIXME add section to Advanced chapter for creating modules, and -@c move this there. -@anchor{Module Loading} -@subheading Loading -@cindex module loading - -ERC loads internal modules in alphabetical order and third-party -modules as they appear in @code{erc-modules}. When defining your own -module, take care to ensure ERC can find it. An easy way to do that -is by mimicking the example in the doc string for -@code{define-erc-module} (also shown below). For historical reasons, -ERC falls back to @code{require}ing features. For example, if some -module @code{my-module} in @code{erc-modules} lacks a corresponding -@code{erc-my-module-mode} command, ERC will attempt to load the -library @code{erc-my-module} prior to connecting. If this fails, ERC -signals an error. Users defining personal modules in an init file -should @code{(provide 'erc-my-module)} somewhere to placate ERC. -Dynamically generating modules on the fly is not supported. - -Some older built-in modules have a second name along with a second -minor-mode toggle, which is just a function alias for its primary -counterpart. For practical reasons, ERC does not define a -corresponding variable alias because contending with indirect -variables complicates bookkeeping tasks, such as persisting module -state across IRC sessions. New modules should definitely avoid -defining aliases without a good reason. - -Some packages have been known to autoload a module's definition -instead of its minor-mode command, which severs the link between the -library and the module. This means that enabling the mode by invoking -its command toggle isn't enough to load its defining library. As -such, packages should only supply module-related autoload cookies with -an actual @code{autoload} form for their module's minor-mode command, -like so: - -@lisp -;;;###autoload(autoload 'erc-my-module-mode "erc-my-module" nil t) -(define-erc-module my-module nil - "My doc string." - ((add-hook 'erc-insert-post-hook #'erc-my-module-on-insert-post)) - ((remove-hook 'erc-insert-post-hook #'erc-my-module-on-insert-post))) -@end lisp - -@noindent -As implied earlier, packages can usually omit such cookies entirely so -long as their module's prefixed name matches that of its defining -library and the library's provided feature. - -Finally, packages have also been observed to run -@code{erc-update-modules} in top-level forms, forcing ERC to take -special precautions to avoid recursive invocations. Another -unfortunate practice is mutating @code{erc-modules} itself upon -loading @code{erc}, possibly by way of an autoload. Doing this tricks -Customize into displaying the widget for @code{erc-modules} -incorrectly, with built-in modules moved from the predefined checklist -to the user-provided free-form area. - -@c PRE5_4: Document every option of every module in its own subnode - - -@node Advanced Usage -@chapter Advanced Usage -@cindex advanced topics - -@menu -* Connecting:: Ways of connecting to an IRC server. -* SASL:: Authenticating via SASL. -* Sample Configuration:: An example configuration file. -* Integrations:: Integrations available for ERC. -* Options:: Options that are available for ERC. - -@detailmenu ---- Detailed Node Listing --- - -Integrations - -* URL:: Opening IRC URLs in ERC. -* SOCKS:: Connecting to IRC with a SOCKS proxy. -* auth-source:: Retrieving auth-source entries with ERC. -* display-buffer:: Controlling how ERC displays buffers. - -@end detailmenu -@end menu - -@node Connecting -@section Connecting to an IRC Server -@cindex connecting - -The easiest way to connect to an IRC server is to call @kbd{M-x erc}. -If you want to assign this function to a keystroke, the following will -help you figure out its parameters. - -@defun erc -Select connection parameters and run ERC@. -Non-interactively, it takes the following keyword arguments. - -@itemize @bullet -@item @var{server} -@item @var{port} -@item @var{nick} -@item @var{user} -@item @var{password} -@item @var{full-name} -@item @var{id} -@end itemize - -For example, calling the command like so - -@example lisp -(erc :server "irc.libera.chat" :full-name "J. Random Hacker") -@end example - -@noindent -sets @var{server} and @var{full-name} directly while leaving the rest -up to functions like @code{erc-compute-port}. Note that some -arguments can't be specified interactively. @var{id}, in particular, -is rarely needed (@pxref{Network Identifier}). - -@end defun - -@noindent -To connect securely over an encrypted TLS connection, use @kbd{M-x -erc-tls}. - -@defun erc-tls -Select connection parameters and run ERC over TLS@. -Non-interactively, it takes the following keyword arguments. - -@itemize @bullet -@item @var{server} -@item @var{port} -@item @var{nick} -@item @var{user} -@item @var{password} -@item @var{full-name} -@item @var{id} -@item @var{client-certificate} -@end itemize - -That is, if called in the following manner - -@example lisp -(erc-tls :server "irc.libera.chat" :full-name "J. Random Hacker") -@end example - -@noindent -the command will set @var{server} and @var{full-name} accordingly, -while helpers, like @code{erc-compute-nick}, will determine other -parameters, and some, like @code{client-certificate}, will just be -@code{nil}. - -@anchor{client-certificate} -To use a certificate with @code{erc-tls}, specify the optional -@var{client-certificate} keyword argument, whose value should be as -described in the documentation of @code{open-network-stream}: if -non-@code{nil}, it should either be a list where the first element is -the file name of the private key corresponding to a client certificate -and the second element is the file name of the client certificate -itself to use when connecting over TLS, or @code{t}, which means that -@code{auth-source} will be queried for the private key and the -certificate. Authenticating using a TLS client certificate is also -referred to as ``CertFP'' (Certificate Fingerprint) authentication by -various IRC networks. - -Examples of use: - -@example -(erc-tls :server "irc.libera.chat" :port 6697 - :client-certificate - (list (expand-file-name "~/key.pem") - (expand-file-name "~/cert.pem"))) -@end example - -@example -(erc-tls :server "irc.libera.chat" :port 6697 - :client-certificate - '("/home/bandali/libera.pem" - "/home/bandali/libera.pem")) ; same file -@end example - -@example -(erc-tls :server "irc.libera.chat" :port 6697 - :client-certificate t) -@end example - -Make sure to use absolute file names for the key and the cert. The -files themselves must be in @acronym{PEM}-encoded text format and can be -concatenated into a single file. - -In the case of @code{:client-certificate t}, you will need to add a -line like the following to your authinfo file -(for example, @file{~/.authinfo.gpg}): - -@example -machine irc.libera.chat key /home/bandali/key.pem cert /home/bandali/cert.pem -@end example - -@xref{Help for users,,,auth, Emacs auth-source Library}, for more on the -@file{.authinfo}/@file{.netrc} backend of @code{auth-source}. -If you invoke @code{erc-tls} interactively and need ERC to query -auth-source for a client cert, see the user option -@code{network-stream-use-client-certificates}. -For other uses of auth-source throughout ERC, @pxref{auth-source, -ERC's auth-source integration}. -@end defun - -@subheading Server - -@defun erc-compute-server &optional server -Return an IRC server name. - -This tries a progressively greater number of default methods until a -non-@code{nil} value is found. - -@itemize @bullet -@item @var{server} (the argument passed to this function) -@item The @code{erc-server} option -@item The value of the IRCSERVER environment variable -@item The @code{erc-default-server} variable -@end itemize - -@end defun - -@defopt erc-server -IRC server to use if one is not provided. -@end defopt - -@subheading Port - -@defun erc-compute-port &optional port -Return a port for an IRC server. - -This tries a progressively greater number of default methods until a -non-@code{nil} value is found. - -@itemize @bullet -@item @var{port} (the argument passed to this function) -@item The @code{erc-port} option -@item The @code{erc-default-port} variable -@end itemize - -@end defun - -@defopt erc-port -IRC port to use if not specified. - -This can be either a string or a number. -@end defopt - -@subheading Nick - -@defun erc-compute-nick &optional nick -Return user's IRC nick. - -This tries a progressively greater number of default methods until a -non-@code{nil} value is found. - -@itemize -@item @var{nick} (the argument passed to this function) -@item The @code{erc-nick} option -@item The value of the IRCNICK environment variable -@item The result from the @code{user-login-name} function -@end itemize - -@end defun - -@defopt erc-nick -Nickname to use if one is not provided. - -This can be either a string, or a list of strings. -In the latter case, if the first nick in the list is already in use, -other nicks are tried in the list order. -@end defopt - -@defopt erc-show-speaker-membership-status -A boolean for including a channel member's @dfn{status prefix} in -their display name when they speak. -@end defopt - -@defopt erc-nick-uniquifier -The string to append to the nick if it is already in use. -@end defopt - -@defopt erc-try-new-nick-p -If the nickname you chose isn't available, and this option is non-@code{nil}, -ERC should automatically attempt to connect with another nickname. - -You can manually set another nickname with the /NICK command. -@end defopt - -@anchor{username parameter} -@subheading User -@cindex username parameter - -@defun erc-compute-user &optional user -Determine a suitable value to send as the first argument of the -opening @samp{USER} IRC command by consulting the following sources: - -@itemize -@item -@var{user}, the argument passed to this function -@item -The option @code{erc-email-userid}, assuming @code{erc-anonymous-login} -is non-@code{nil} -@item -The result of calling the function @code{user-login-name} -@end itemize - -@end defun - -@defopt erc-email-userid -A permanent username value to send for all connections. It should be -a string abiding by the rules of the network. -@end defopt - -@anchor{password parameter} -@anchor{server password} -@cindex password, server -@subheading Password - -This parameter was traditionally meant to specify a @dfn{server -password} to be sent along with the IRC @samp{PASS} command. However, -such passwords aren't widely used. Instead, networks typically expect -them, when present, to convey other authentication information. In -the case of account-services (a.k.a., ``NickServ'') credentials, this -typically involves a special syntax, such as @samp{myuser:mypass}. -IRC bouncers often do something similar but include a pre-configured -network-ID component, for example, @samp{bncuser/mynet:bncpass}. - -In general, if you have @emph{not} been asked by your network or -bouncer to specify a repurposed server password, you should instead -consider setting up @samp{services} or, preferably, @samp{sasl}, both -ERC modules (@pxref{Modules}). In addition to performing -network-account authentication, these obviate the need for this -parameter completely, although both can optionally borrow it for their -own purposes. (@xref{SASL, SASL in ERC}.) - -@defopt erc-prompt-for-password -If non-@code{nil} (the default), @kbd{M-x erc} and @kbd{M-x erc-tls} -prompt for a server password. This only affects interactive -invocations of @code{erc} and @code{erc-tls}. -@end defopt - -@noindent -If you prefer, you can set this option to @code{nil} and use the -auth-source facility to retrieve a server password, although hitting -@kbd{RET} at the prompt may achieve the same effect. -@xref{auth-source, ERC's auth-source integration}, for more. - -@subheading Full name - -@defun erc-compute-full-name &optional full-name -Return user's full name. - -This tries a progressively greater number of default methods until a -non-@code{nil} value is found. - -@itemize @bullet -@item -@var{full-name} (the argument passed to this function) -@item -The @code{erc-user-full-name} option -@item -The value of the IRCNAME environment variable -@item -The result from the @code{user-full-name} function -@end itemize - -@end defun - -@defopt erc-user-full-name -User full name. - -This can be either a string or a function to call. -@end defopt - - -@anchor{Network Identifier} -@subheading ID - -ERC uses an abstract designation, called @dfn{network context -identifier}, for referring to a connection internally. While normally -derived from a combination of logical and physical connection -parameters, an ID can also be explicitly provided via an entry-point -command (like @code{erc-tls}). Use this in rare situations where ERC -would otherwise have trouble discerning between connections. - -One such situation might arise when using multiple connections to the -same network with the same nick but different (nonstandard) @samp{device} -identifiers, which some bouncers may support. Another might be when -mimicking the experience offered by popular standalone clients, which -normally offer ``named'' persistent configurations with server buffers -reflecting those names. Yet another use case might involve -third-party code needing to identify a connection unequivocally, but in -a human-friendly way suitable for UI components. - -When providing an ID as an entry-point argument, strings and symbols -make the most sense, but any reasonably printable object is -acceptable. - -@node SASL -@section Authenticating via SASL -@cindex SASL - -If you've used @acronym{SASL} elsewhere, you can probably skip to the -examples below. Otherwise, if you haven't already registered with -your network, please do so now, referring to the network's own -instructions for details. If you're new to IRC and using a bouncer, -know that you probably won't be needing this for the client-to-bouncer -connection. - -When you're ready to get started, add @code{sasl} to -@code{erc-modules}, like you would any other module. If unsure which -@dfn{mechanism} to choose, stick with the default of @samp{PLAIN}. -Then try @kbd{C-u M-x erc-tls @key{RET}}, and give your account name -for the @samp{user} parameter and your account password for the -@samp{server password}. - -@defopt erc-sasl-mechanism -The name of an SASL subprotocol type as a @emph{lowercase} symbol. -The value can be one of the following: - -@table @asis -@item @code{plain} or @code{scram} (``password-based'') -Here, ``password'' refers to your account password, which is usually -your @samp{NickServ} password. To make this work, customize -@code{erc-sasl-user} and @code{erc-sasl-password} or specify the -@code{:user} and @code{:password} keyword arguments when invoking -@code{erc-tls}. - -@item @code{external} (via client @acronym{TLS} certificate) -This works in conjunction with the @code{:client-certificate} keyword -offered by @code{erc-tls}. Just ensure you've registered your -fingerprint with the network beforehand. The fingerprint is usually a -SHA1 or SHA256 digest in either "normalized" or "openssl" forms. The -first is lowercase without delims (@samp{deadbeef}) and the second -uppercase with colon seps (@samp{DE:AD:BE:EF}). These days, there's -usually a @samp{CERT ADD} command offered by NickServ that can -register you automatically if you issue it while connected with a -client cert. @xref{client-certificate}. - -Additional considerations: -@enumerate -@item -Most IRCds will allow you to authenticate with a client cert but -without the hassle of SASL (meaning you may not need this module). -@item -Technically, @var{EXTERNAL} merely indicates that an out-of-band mode -of authentication is in effect (being deferred to), so depending on -the specific application or service, there's a remote chance your -server has something else in mind. -@end enumerate - -@item @code{ecdsa-nist256p-challenge} -This mechanism is quite complicated and currently requires the -external @samp{openssl} executable, so please use something else if at -all possible. Ignoring that, specify your key file (e.g., -@samp{~/pki/mykey.pem}) as the value of @code{erc-sasl-password}, and -then configure your network settings. On servers running Atheme -services, you can add your public key with @samp{NickServ} like so: - -@example -ERC> /msg NickServ set property \ - pubkey AgGZmlYTUjJlea/BVz7yrjJ6gysiAPaQxzeUzTH4hd5j - -@end example -(You may be able to omit the @samp{property} subcommand.) -@end table - -@end defopt - -@defopt erc-sasl-user -This should be your network account username, typically the same one -registered with nickname services. Specify this when your NickServ -login differs from the @code{:user} you're connecting with. -@xref{username parameter}. -@end defopt - -@defopt erc-sasl-password -As noted elsewhere, the entry-point @code{:password} param was -originally intended for traditional ``server passwords,'' but these -aren't really used any more (@pxref{password parameter}). As such, -this option defaults to borrowing that parameter for its own uses, -thus allowing you to call @code{erc-tls} with @code{:password} set to -your NickServ password. - -You can also set this to a nonemtpy string, and ERC will send that -when needed, no questions asked. Or, if you'd rather use auth-source, -set @code{erc-sasl-auth-source-function} to a function, and ERC will -perform an auth-source query instead. In all cases, ERC will prompt -you for input as a last resort. - -Lastly, if your mechanism is @code{ecdsa-nist256p-challenge}, this -option should instead hold the file name of your key. -@end defopt - -@anchor{SASL auth-source function} -@defopt erc-sasl-auth-source-function -This is nearly identical to the other ERC @samp{auth-source} function -options (@pxref{auth-source functions}) except that the default value -here is @code{nil}, meaning you have to set it to something like -@code{erc-auth-source-search} for queries to be performed. For -convenience, this module provides the following as a possible value: - -@defun erc-sasl-auth-source-password-as-host &rest plist -Setting @code{erc-sasl-auth-source-function} to this function tells -ERC to use @code{erc-sasl-password} for the @code{:host} field when -querying auth-source, even if its value is the default -@code{:password}, in which case ERC knows to ``resolve'' it to -@code{erc-session-password} and use that as long as it's -non-@code{nil}. Otherwise, ERC just defers to -@code{erc-auth-source-search} to determine the @code{:host}, along -with everything else. -@end defun - -As long as this option specifies a function, ERC will pass it the -``resolved'' value of @code{erc-sasl-user} for the auth-source -@code{:user} param. -@end defopt - -@defopt erc-sasl-authzid -In the rarest of circumstances, a network may want you to specify a -specific role or assume an alternate identity. In most cases, this -happens because the server is buggy or misconfigured. If you suspect -such a thing, please contact your network operator. Otherwise, just -leave this set to @code{nil}. -@end defopt - -@subheading Examples - -@itemize @bullet -@item -Defaults - -@lisp -(erc-tls :server "irc.libera.chat" :port 6697 - :nick "aph" - :user "APHacker" - :password "changeme") -@end lisp - -Here, after adding @code{sasl} to @code{erc-modules} via the Customize -interface, you authenticate to Libera.Chat using the @samp{PLAIN} -mechanism and your NickServ credentials, @samp{APHacker} and -@samp{changeme}. - -@item -External - -@lisp -(setopt erc-sasl-mechanism 'external) - -(erc-tls :server "irc.libera.chat" :port 6697 :nick "aph" - :client-certificate - '("/home/aph/key.pem" "/home/aph/cert.pem")) -@end lisp - -You decide to switch things up and try out the @samp{EXTERNAL} -mechanism. You follow your network's instructions for telling -NickServ about your client-certificate's fingerprint, and you -authenticate successfully. - -@item -Multiple networks - -@example -# ~/.authinfo.gpg - -machine irc.libera.chat key /home/aph/key.pem cert /home/aph/cert.pem -machine Example.Net login alyssa password sEcReT -machine Example.Net login aph-bot password sesame -@end example - -@lisp -;; init.el - -(defun my-erc-up (network) - (interactive "Snetwork: ") - (require 'erc-sasl) - (or (let ((erc-modules (cons 'sasl erc-modules))) - (pcase network - ('libera - (let ((erc-sasl-mechanism 'external)) - (erc-tls :server "irc.libera.chat" - :client-certificate t))) - ('example - (let ((erc-sasl-auth-source-function - #'erc-sasl-auth-source-password-as-host)) - (erc-tls :server "irc.example.net" - :user "alyssa" - :password "Example.Net"))))) - ;; Non-SASL - (call-interactively #'erc-tls))) -@end lisp - -You've started storing your credentials with auth-source and have -decided to try SASL on another network as well. But there's a catch: -this network doesn't support @samp{EXTERNAL}. You use -@code{let}-binding to work around this and successfully authenticate -to both networks. (Note that this example assumes you've removed -@code{sasl} from @code{erc-modules} globally and have instead opted to -add it locally when connecting to preconfigured networks.) - -@end itemize - -@subheading Troubleshooting - -First and foremost, please know that ERC's SASL offering is currently -limited by a lack of support for proper IRCv3 capability negotiation. -In most cases, this shouldn't affect your ability to authenticate. - -If you're struggling, remember that your SASL password is almost -always your NickServ password. When in doubt, try restoring all SASL -options to their defaults and calling @code{erc-tls} with @code{:user} -set to your NickServ account name and @code{:password} to your -NickServ password. If you're still having trouble, please contact us -(@pxref{Getting Help and Reporting Bugs}). - -As you try out different settings, keep in mind that it's best to -create a fresh session for every change, for example, by calling -@code{erc-tls} from scratch. More experienced users may be able to -get away with cycling @code{erc-sasl-mode} and issuing a -@samp{/reconnect}, but that's generally not recommended. Whatever the -case, you'll probably want to temporarily disable -@code{erc-server-auto-reconnect} while experimenting. - -@node Sample Configuration -@section Sample Configuration -@cindex configuration, sample - -Here is an example configuration for ERC@. @strong{Don't panic} if -you aren't familiar with @samp{use-package} or have no interest in -learning it. For our purposes, it's just a means of presenting -configuration details in a tidy, standardized format. If it helps, -just pretend it's some make-believe, pseudo configuration language. -And while the syntax below is easy enough to intuit and adapt to your -setup, you may wish to keep the following in mind: - -@itemize @bullet -@item -Each @code{use-package} ``declaration'' focuses on a library -``feature'', which is just a symbol you'd normally @code{require} in -your config. - -@item -Emacs loads anything in a @code{:config} section @emph{after} loading -whatever library @code{provide}s the declaration's feature. - -@item -Everything in a @code{:custom} or @code{:custom-face} section is -basically something you'd find in your @code{custom-file}. - -@item -For more info, @pxref{Named Features,,, elisp,}, or @pxref{Top,,, -use-package,}. -@end itemize - -@noindent -The following would typically go in your init file. Experienced users -may opt to keep any non-settings, like commands and functions, in a -dedicated @file{~/.emacs.d/.ercrc.el}. Whatever the case, please keep -in mind that you can replace nearly all of the following with Custom -settings (@pxref{Sample configuration via Customize}). - -@lisp -;;; My ERC configuration -*- lexical-binding: t -*- - -(use-package erc - :config - ;; Prefer SASL to NickServ, colorize nicknames, and show side panels - ;; with joined channels and members - (setopt erc-modules - (seq-union '(sasl nicks bufbar nickbar scrolltobottom) - erc-modules)) - - :custom - ;; Protect me from accidentally sending excess lines. - (erc-inhibit-multiline-input t) - (erc-send-whitespace-lines t) - (erc-ask-about-multiline-input t) - ;; Scroll all windows to prompt when submitting input. - (erc-scrolltobottom-all t) - - ;; Wait a bit longer between automatic reconnect attempts. - (erc-server-reconnect-timeout 30) - - ;; Show new buffers in the current window instead of a split. - (erc-interactive-display 'buffer) - - ;; Insert a newline when I hit at the prompt, and prefer - ;; something more deliberate for actually sending messages. - :bind (:map erc-mode-map - ("RET" . nil) - ("C-c C-c" . #'erc-send-current-line)) - - ;; Emphasize buttonized text in notices. - :custom-face (erc-notice-face ((t (:slant italic :weight unspecified))))) - -(use-package erc-sasl - ;; Since my account name is the same as my nick, free me from having - ;; to hit C-u before M-x erc to trigger a username prompt. - :custom (erc-sasl-user :nick)) - -(use-package erc-join - ;; Join #emacs and #erc whenever I connect to Libera.Chat. - :custom (erc-autojoin-channels-alist '((Libera.Chat "#emacs" "#erc")))) - -(use-package erc-fill - :custom - ;; Prefer one message per line without continuation indicators. - (erc-fill-function #'erc-fill-wrap) - (erc-fill-static-center 18) - - :bind (:map erc-fill-wrap-mode-map ("C-c =" . #'erc-fill-wrap-nudge))) - -(use-package erc-match - ;; Use the same face for my own nick wherever it appears. - :custom-face - (erc-current-nick-face ((t ( :weight unspecified - :foreground unspecified - :inherit erc-my-nick-face))))) - -(use-package erc-track - ;; Prevent JOINs and PARTs from lighting up the mode-line. - :config (setopt erc-track-faces-priority-list - (remq 'erc-notice-face erc-track-faces-priority-list)) - - :custom (erc-track-priority-faces-only 'all)) - -(use-package erc-goodies - ;; Turn on read indicators when joining channels. - :hook (erc-join . my-erc-enable-keep-place-indicator-on-join)) - -(defvar my-erc-read-indicator-channels '("#emacs") - "Channels in which to show a `keep-place-indicator'.") - -(defun my-erc-enable-keep-place-indicator-on-join () - "Enable read indicators for certain queries or channels." - (when (member (erc-default-target) my-erc-read-indicator-channels) - (erc-keep-place-indicator-mode +1))) - -;; Handy commands from the Emacs Wiki. -(defun erc-cmd-TRACK (&optional target) - "Start tracking TARGET or that of current buffer." - (setq erc-track-exclude - (delete (or target (erc-default-target) (current-buffer)) - erc-track-exclude))) - -(defun erc-cmd-UNTRACK (&optional target) - "Stop tracking TARGET or that of current buffer." - (setq erc-track-exclude - (cl-pushnew (or target (erc-default-target) (current-buffer)) - erc-track-exclude - :test #'equal))) - -@end lisp - -@noindent -Those familiar with @code{use-package} may have noticed the lack of -@code{:defer} keyword args. This was done to conserve space, but you -can just pretend that this user has enabled -@code{use-package-always-defer} elsewhere. - -@anchor{Sample configuration via Customize} -@subheading Via Customize -@cindex configuration, via customize - -As mentioned, Customize users can accomplish nearly all of the above -via the Customize interface. Start by running @kbd{M-x -customize-group @key{RET} erc @key{RET}}, and search for ``Modules'' -with @kbd{C-s modules @key{RET}}. Toggle open the flyout menu to -reveal the full @dfn{widget} panel, a web-form-like interface for -``Erc Modules''. Tick the boxes for @samp{bufbar}, @samp{nickbar}, -@samp{nicks}, @samp{sasl}, and @samp{scrolltobottom}. - -Next, search for the phrases ``Erc Ask About Multiline Input'', ``Erc -Inhibit Multiline Input'', and ``Erc Send Whitespace Lines''. These -are the print names of three boolean options that control how ERC -treats prompt input containing line breaks. When visiting each -option's section, twirl open its triangle icon to reveal its widget -UI, and click its @samp{[Toggle]} button to set its value to @code{t}. -While going about this, you may find it helpful to glance at the -descriptions just in case you want to disable them later. When -finished, hit @kbd{C-x C-s} or click @samp{[Apply and Save]} atop the -buffer. - -Now do the same for another option, this time having to do with -automatic reconnection. But instead of searching for its print name, -try running @kbd{M-x customize-option @key{RET} -erc-server-reconnect-timeout @key{RET}}. (If it helps, hit @key{TAB} -for completion.) As you may have noticed, when customizing options -individually, each buffer displays but a single option's widget. For -@code{erc-server-reconnect-timeout}, you'll encounter a text field -(instead of a button), which works like those in a typical web form. -Enter @samp{30} and either hit @kbd{C-x C-s} to save or @key{TAB} over -to @samp{[State]} and hit @key{RET} followed by @kbd{1} to persist your -changes. - -Just for fun, click the group link for @samp{Erc Server} at the bottom -of the buffer. You could just as well have set the last two options -from this ``custom group'' buffer alone, which very much resembles the -one for the @samp{Erc} group, which is actually the ``parent'' of this -group (note the ``breadcrumb'' for group @samp{Erc} atop the buffer). -Indeed, you can always get back here by running @kbd{M-x -customize-group @key{RET} erc-server @key{RET}} from almost anywhere -in Emacs. - -To make sure you've got this, try quickly customizing the option -@code{erc-interactive-display}, which lives in the @samp{Erc Buffers} -group (@kbd{M-x customize-group @key{RET} erc-buffers @key{RET}}). As -its doc string explains, the option controls where new buffers show up -when you do @kbd{M-x erc-tls @key{RET}} or issue certain @dfn{slash -commands}, like @kbd{/JOIN #emacs-beginners @key{RET}}, at ERC's -prompt. Change its value to the symbol @code{buffer} by choosing -@samp{Use current window} (item @kbd{5}) from the option's -@samp{[Value Menu]}. Don't forget to save. - -If you need more practice, try enabling the boolean option -@code{erc-scrolltobottom-all}, which lives in the @samp{Erc Display} -group (@kbd{M-x customize-group @key{RET} erc-display @key{RET}}). -When enabled, this option tells the @samp{scrolltobottom} module to -adjust all ERC windows instead of just the one you're currently typing -in. - -Now it's time to set some key bindings for @code{erc-mode-map}, a -major-mode keymap active in all ERC buffers. In general, it's best to -do this part either entirely or in conjunction with some lisp code in -you init file. However, to keep things ``simple'', we'll do it all in -customization buffers. To get started, hit @kbd{M-x customize-group -@key{RET} erc-hooks @key{RET}} and search for ``Erc Mode Hook''. In -the widget form, click @samp{[INS]}, and paste the following into the -value field in place of the default text. - -@lisp -(lambda () - (keymap-set erc-mode-map "RET" nil) - (keymap-set erc-mode-map "C-c C-c" 'erc-send-current-line)) -@end lisp - -@noindent -Don't worry about the line breaks. Emacs is smart enough to handle -those. When you're ready, click @samp{[Apply and Save]}. - -Next, try tweaking the face ERC uses to stylize server messages that -say things like ``SoAndSo has joined channel #chan''. Type @kbd{M-x -customize-face @key{RET} erc-notice-face @key{RET}}. Click the -``link''-looking button at the very bottom that says something like -``Show All Attributes''. Untick @samp{Weight} and tick @samp{Slant}. -Then, in the latter's @samp{[Value Menu]}, enter @samp{0} for -@samp{italic}. Hit @kbd{C-x C-s} to save. - -Time for some more involved configuring. From now on, if something -isn't applicable to your setup, just skip ahead. Also, note that if -you've installed ERC from GNU ELPA, you may need to load libraries for -groups and options you'd like to customize before Emacs can create a -customization buffer. For example, to do this for the group -@code{erc-sasl}, run @kbd{M-: (require 'erc-sasl) @key{RET}}. - -Speaking of @acronym{SASL}, those already authenticating with it may -have noticed that connecting interactively requires running @kbd{C-u -M-x erc-tls @key{RET}} in order to receive a ``User'' prompt for your -account name. However, if your nickname happens to be the same as -your account name, you can avoid the leading @kbd{C-u} by customizing -the option @code{erc-sasl-user} to the keyword symbol @code{:nick}. -At the time of writing, you'd hit @kbd{2} when prompted by the -option's @samp{[Value menu]}. Hit @kbd{C-x C-s} to save your changes. - -One of ERC's most configured options lives in @file{erc-join}, and it -determines the channels you join upon connecting. To make it work for -you, customize the option @code{erc-autojoin-channels-alist}. In the -customization widget, hit @samp{[INS]} to create a new entry. In the -@samp{Network:} field, type @samp{Libera.Chat}. Under -@samp{Channels:}, hit @samp{[INS]} again, this time to create a field -to enter a channel name, and enter @samp{#emacs}. Now, find and click -on the lowermost @samp{[INS]}, and this time enter @samp{#erc} in the -@samp{Name:} field. Save your changes. - -If you're new to ERC, you may not be familiar with the various ways it -can ``fill'' message text by inserting line breaks. The most modern -fill style is called @code{fill-wrap}, and it's available by -customizing @code{erc-fill-function} to @code{erc-fill-wrap}, which -appears as @samp{Dynamic word-wrap} in the option's @samp{[Value -Menu]}. After setting this, change the related option -@code{erc-fill-static-center} to the integer @samp{18}. Save your -changes. As a bonus exercise, try binding the key @kbd{C-c =} to the -function @code{erc-fill-wrap-nudge} in the minor-mode keymap -@code{erc-fill-wrap-mode-map} (hint: the minor mode's hook is called -@code{erc-fill-wrap-mode-hook}, and it's not a member of any -customization group). - -Try customizing another face, this time with inheritance. ERC's match -module highlights your nick whenever someone mentions you in -conversation. However, some users don't like that this face differs -from the one in your own messages. Let's change that. Type @kbd{M-x -customize-group @key{RET} erc-faces @key{RET}}. Either search for the -word ``Current'' or type @kbd{M-x customize-face @key{RET} -erc-current-nick-face @key{RET}}. Untick @samp{Weight} and -@samp{Foreground}, then click the ``Show All Attributes'' button below -them. Navigate down to the @samp{Inherit} box, tick it, hit -@samp{[INS]}, and type @code{erc-my-nick-face} in the @samp{Face} field. -Hit @kbd{C-x C-s} to save. - -ERC users tend to be picky about the mode line. If you find that -you'd rather not see changes when people join and leave channels, -customize the option @code{erc-track-faces-priority-list}. When -visiting its customization buffer, you'll notice it's quite busy. -Ignore everything and type @kbd{C-s erc-notice-face @key{RET}}. Click -the @samp{[DEL]} button at the beginning of the line you end up on, -and save your changes. Next, customize the related option -@code{erc-track-priority-faces-only} to the @samp{[Value Menu]} choice -@samp{all}. Once again, save your changes. - -Let's say you'd like to enable a @dfn{local module} (ERC's version of -a local minor mode) in a specific channel. One way to do that is by -running some code to activate the module if the channel's name -matches. Try that now by customizing the option @code{erc-join-hook}. -Add the following in the value field before saving your changes: - -@lisp -(lambda () - (require 'erc-goodies) - (when (equal (erc-default-target) "#emacs") - (erc-keep-place-indicator-mode +1))) -@end lisp - -Lastly, if you really want the two @dfn{slash commands} defined at the -end of the previous section, you can put them in any file listed in -@code{erc-startup-file-list}, such as @file{~/.emacs.d/.ercrc.el}. -Make sure to put @code{(require 'erc-track)} near the top of the file. -These will allow you to type @kbd{/TRACK @key{RET}} and @kbd{/UNTRACK -@key{RET}} in channels and query buffers to tell ERC whether to show -activity from these buffers in the mode line. - - -@node Integrations -@section Integrations -@cindex integrations - -@menu -* auth-source:: Retrieving auth-source entries with ERC. -* display-buffer:: Controlling how ERC displays buffers. -@end menu - -@anchor{URL} -@subsection URL -@cindex URL - -For anything to work, you'll want to set @code{url-irc-function} to -@code{url-irc-erc}. As a rule of thumb, libraries relying directly on -@code{url-retrieve} should be fine out the box from Emacs 29.1 onward. -On older versions of Emacs, you may need to @code{(require 'erc)} -beforehand. @xref{Retrieving URLs,,, url, URL}. - -For other apps and libraries, such as those relying on the -higher-level @code{browse-url}, you'll oftentimes be asked to specify -a pattern, sometimes paired with a function that accepts a string URL -as a first argument. For example, with EWW, you may need to tack -something like @code{"\\|\\`irc6?s?:"} onto the end of -@code{eww-use-browse-url}. But with @code{gnus-button-alist}, you'll -need a function as well: - -@lisp - '("\\birc6?s?://[][a-z0-9.,@@_:+%?&/#-]+" 0 t browse-url-irc 0) -@end lisp - -@noindent -Users on Emacs 28 and below may need to use @code{browse-url} instead. - -@anchor{SOCKS} -@subsection SOCKS -@cindex SOCKS - -People wanting to connect to IRC through a @acronym{SOCKS} proxy are -most likely interested in doing so over @acronym{TOR} (The Onion -Router). If that's @emph{not} you, please adapt these instructions -accordingly. Otherwise, keep in mind that support for Tor is -experimental and thus insufficient for safeguarding a user's identity -and location, especially in the case of targeted individuals. - -ERC's preferred Tor setup works by accessing a local Tor service -through the built-in @file{socks.el} library that ships with Emacs. -Other means of accessing Tor, such as via @command{torsocks}, are not -supported. Before getting started, check that your Tor service is up -and running. You can do that with the following command: - -@example -curl --proxy socks5h://localhost:9050 https://check.torproject.org | \ - grep 'Congratulations' -@end example - -Networks and servers differ in how they expose Tor endpoints. In all -cases, you'll want to first set the option @code{socks-server} to -something appropriate, like @code{("tor" "127.0.0.1" 9050 5)}. For -some networks, setting @code{erc-server-connect-function} to -@code{socks-open-network-stream} might be enough. Others, like -@samp{Libera.Chat}, involve additional setup. At the time of writing, -connecting to that network requires both @acronym{TLS} and a permitted -@acronym{SASL} mechanism, like @samp{EXTERNAL} (@pxref{SASL}), as -shown in the following example: - -@lisp -(require 'erc) -(require 'socks) - -(defun my-erc-open-socks-tls-stream (&rest args) - (let ((socks-username "") - (socks-password "") - (socks-server '("tor" "localhost" 9050 5))) - (apply #'erc-open-socks-tls-stream args))) - -(setopt erc-server-reconnect-function #'erc-server-delayed-check-reconnect) - -(let* ((erc-modules (cons 'sasl erc-modules)) - (erc-sasl-mechanism 'external) - (erc-server-connect-function #'my-erc-open-socks-tls-stream)) - (erc-tls - :server "libera75jm6of4wxpxt4aynol3xjmbtxgfyjpu34ss4d7r7q2v5zrpyd.onion" - :port 6697 - :nick "jrh" - :user "jrandomhacker" - :full-name "J. Random Hacker" - :client-certificate (list "/home/jrh/key.pem" "/home/jrh/cert.pem"))) -@end lisp - -@noindent -Here, the user-provided @code{my-erc-open-socks-tls-stream} ensures -that the preferred values for @code{socks-server} and friends will be -available when reconnecting. If you plan on using @acronym{SOCKS} -with ERC exclusively, you can just set those options and variables -globally and bind @code{erc-server-connect-function} to -@code{erc-open-socks-tls-stream} instead. - -@defun erc-open-socks-tls-stream -The default TLS @dfn{connector} for @acronym{SOCKS} connections. -Compatible with option @code{erc-server-connect-function}. Be aware -that if used in conjunction with certain values of -@code{erc-server-reconnect-function} (such as -@code{erc-server-prefer-check-reconnect}, currently the default -@dfn{reconnector}, or @code{erc-server-delayed-check-reconnect}, the -more specialized workhorse it defers to), this function may cause ERC to -misreport proxy-related failures as routine lapses in internet -connectivity. -@end defun - -@node auth-source -@subsection auth-source -@cindex auth-source - -You can configure ERC to use the built-in auth-source library for -looking up passwords. @xref{Top,,auth-source, auth, Emacs auth-source -Library}, for general info on setting up various backends, but keep in -mind that some of these may not be compatible. Those currently -supported are netrc, plstore, json, secrets, and pass. To get started -with the default backend, netrc, put a line like the following in your -@file{~/.authinfo.gpg} (or any file named in the option -@code{auth-sources}): - -@example -machine irc.example.net login mynick password sEcReT -@end example - -@anchor{auth-source Server Password} -@subsubheading Server Passwords -When retrieving passwords to accompany the IRC @samp{PASS} command -(@pxref{password parameter}), ERC asks auth-source to match the -@var{server} parameter of @code{erc-tls} against each entry's -@samp{host} field (@w{@code{machine irc.example.net}} in the above -example). Unfortunately, specifying a network, like -@samp{Libera.Chat}, or a specific network server, like -@samp{platinum.libera.chat}, won't normally work for looking up a -server password because that information isn't available during -opening introductions. (Actually, ERC @emph{can} find entries with -arbitrary @samp{host} values for any context, including server -passwords, but that requires customizing the more advanced options -below.) - -If ERC can't find a suitable server password, it will just skip the -IRC @samp{PASS} command altogether, something users may want when -using CertFP or engaging NickServ via ERC's @code{services} module. -If that appeals to you, consider customizing the option -@code{erc-auth-source-server-function} to @code{nil} to skip -server-password lookup for all servers. Note that some networks and -IRCds may accept account-services authentication via server password. -Also, some ERC modules may commandeer the @code{erc-tls} -@var{password} parameter for their own ends, which likely don't -involve a server password. - -@subsubheading The @samp{services} module -You can use auth-source to authenticate to account services the -traditional way through a bot called @samp{NickServ}. To do so, add -@code{services} to @code{erc-modules} and set the option -@code{erc-use-auth-source-for-nickserv-password} to @code{t}. After -that, expect the @samp{user} parameter in relevant auth-source queries -to be your current nickname. - -Most of the time, a query's precise contextual details (such as -whether a nick was granted or forcibly assigned) shouldn't affect how -you define entries in your backend. However, if something isn't quite -working, you may want to investigate the interplay between the option -@code{erc-nickserv-identify-mode} and account services. In -particular, if you find yourself facing nicks suffixed with an -@code{erc-nick-uniquifier} (the infamous @samp{`}), check that the -network's entry in @code{erc-nickserv-alist} is up to date, and do let -us know if something's off (@pxref{Getting Help and Reporting Bugs}). -Of course, if you've had your fill of fiddling with this module, -consider switching to SASL for what's likely a more consistent -auth-source experience. (@xref{SASL}.) - -@subsubheading Default query behavior -When preparing entries for your backend, it may help to get a feel for -how ERC and its modules conduct searches, especially when exploring a -new context, such as channel keys. Overall, though, ERC tries to be -consistent in performing queries across various authentication -contexts. Here's what to expect with respect to the @samp{host} -field, which, by default, most heavily influences the fate of a query: - -@enumerate -@item -entries featuring custom identifiers and networks are matched first -(@pxref{Network Identifier}) -@item -followed by network-specific servers -@item -and, finally, dialed endpoints (typically the @var{server} argument -passed to @code{erc-tls}) -@end enumerate - -@noindent -The following netrc-style entries appear in order of precedence: - -@example -machine Libera/cellphone login MyNick password sEcReT -machine Libera.Chat login MyNick password sEcReT -machine zirconium.libera.chat login MyNick password sEcReT -machine irc.libera.chat login MyNick password sEcReT -@end example - -@noindent -Remember that field labels vary per backend, so @samp{machine} (in -netrc's case) maps to auth-source's generalized notion of a host, -hence the @samp{:host} keyword parameter to @code{auth-source-search}. -Also, be sure to mind the syntax of your chosen backend medium. For -example, always quote channel names in a netrc file. - -Lastly, if this all seems overly nuanced or just plain doesn't appeal -to you, please see options @code{erc-auth-source-services-function} -and friends, described just below. - -@subsubheading Custom query functions -These let you query auth-source your way. Most users can -simply ignore the passed-in arguments and get by with something like -the following: - -@lisp -(defun my-fancy-auth-source-func (&rest _) - (let* ((host (read-string "host: " nil nil "default")) - (pass (auth-source-pick-first-password :host host))) - (if (and pass (string-search "libera" host)) - (concat "MyNick:" pass) - pass))) -@end lisp - -@anchor{auth-source functions} -@defopt erc-auth-source-server-function -@end defopt -@defopt erc-auth-source-services-function -@end defopt -@defopt erc-auth-source-join-function - -ERC calls these functions with keyword arguments recognized by -@code{auth-source-search}, namely, those deemed most relevant to the -current context, if any. For example, when identifying to services, -@code{:user} contains your current nickname. Generalized parameter -names, like @code{:user} and @code{:host}, are always preferred over -backend specific ones, like @code{:login} or @code{:machine}. In -return, ERC expects a string if the search succeeds or @code{nil} if -it fails. - -@findex erc-auth-source-search -The default value for all three options is the function -@code{erc-auth-source-search}. It tries to merge relevant contextual -parameters with those provided or discovered from the logical -connection or the underlying transport. - -For using auth-source along with SASL, @pxref{SASL auth-source -function}. -@end defopt - -@subsubheading Channel keys -ERC also consults @code{auth-source} to find ``keys'' that may be -required by certain channels you join. When modifying a traditional -@code{auth-source} entry for this purpose, put the channel name in the -@samp{user} field (for example, @samp{login "#fsf"}, in netrc's case). -The actual key goes in the @samp{password} (or @samp{secret}) field. - -@anchor{auth-source Troubleshooting} -@subheading Troubleshooting -By default, ERC queries @code{auth-source} for channel keys and server -passwords (@pxref{auth-source Server Password}), as well as other, -module-specific credentials. In general, if you're having trouble -calling @code{auth-source-search} in a custom query function, like -@code{erc-auth-source-server-function}, try temporarily setting the -variable @code{auth-source-debug} to @code{t} and checking -@file{*Messages*} periodically for insights into how -@code{auth-source} is operating. - -If you're using a @acronym{GPG}-encrypted file and find that -customizing one of the function-valued query options doesn't solve -your problem, explore options @code{epg-pinentry-mode} and -@code{epg-debug} in the @code{epg} Custom group (@pxref{GnuPG -Pinentry,,, epa, EasyPG Assistant}). Additionally, keep an eye out -for an @file{*Error*} buffer, which may contain more specific clues -about your situation. If you use the libsecrets integration -(@pxref{Secret Service API,,, auth, Emacs auth-source}) with something -like GNOME Keyring, you may need to check the ``remember'' box in the -passphrase popup dialog to avoid being prompted for confirmation every -time you run ERC. If it doesn't work at first, try logging out. And -when in doubt, try using the Emacs command @code{secrets-show-secrets} -to browse the @samp{Login} keyring. There should be a -@samp{GnuPG/stored-by} entry with a value of @samp{GnuPG Pinentry} or -similar. - -@node display-buffer -@subsection display-buffer -@cindex display-buffer - -ERC supports the ``action'' interface used by @code{display-buffer} -and friends from @file{window.el}. @xref{Displaying Buffers,,, elisp, -Emacs Lisp}, for specifics. When ERC displays a new or -``reassociated'' buffer, it consults its various buffer-display -options, such as @code{erc-buffer-display}, to decide whether and how -the buffer ought to appear in a window. Exactly which one it consults -depends on the context in which the buffer is being manifested. - -For some buffer-display options, the context is pretty cut and dry. -For instance, in the case of @code{erc-receive-query-display}, you're -receiving a query from someone you haven't yet chatted with in the -current session. For other options, like -@code{erc-interactive-display}, the precise context varies. For -example, you might be opening a query buffer with the command -@kbd{/QUERY bob @key{RET}} or joining a new channel with @kbd{/JOIN -#chan @key{RET}}. Power users wishing to distinguish between such -nuanced contexts or just exercise more control over buffer-display -behavior generally can elect to override these options by setting one -or more to a ``@code{display-buffer}-like'' function that accepts a -@var{buffer} and an @var{action} argument. - -@subsubheading Examples - -In this first example, a user-provided buffer-display function -displays new server buffers in the current window when issuing an -@kbd{M-x erc-tls @key{RET}} and in a split window for all other -interactve contexts covered by the option -@code{erc-interactive-display}, like clicking an @samp{irc://}-style -@acronym{URL} (@pxref{URL}). - -@lisp -(defun my-erc-interactive-display-buffer (buffer action) - "Pop to BUFFER when running \\[erc-tls], clicking a link, etc." - (when-let ((alist (cdr action)) - (found (alist-get 'erc-interactive-display alist))) - (if (eq found 'erc-tls) - (pop-to-buffer-same-window buffer action) - (pop-to-buffer buffer action)))) - -(setopt erc-interactive-display #'my-erc-interactive-display-buffer) -@end lisp - -@noindent -Observe that ERC supplies the names of buffer-display options as -@var{action} alist keys and pairs them with contextual constants, like -the symbols @samp{erc-tls} or @samp{url}, the full lineup of which are -listed below. - -In this second example, for Emacs 29 and above, the user writes three -predicates that somewhat resemble the ``@code{display-buffer}-like'' -function above. These too look for @var{action} alist keys sharing -the names of ERC's buffer-display options (and, in one case, a -module's minor mode). - -@lisp -(defun my-erc-disp-entry-p (_ action) - (memq (cdr (or (assq 'erc-buffer-display action) - (assq 'erc-interactive-display action))) - '(erc-tls url))) - -(defun my-erc-disp-query-p (_ action) - (or (eq (cdr (assq 'erc-interactive-display action)) '/QUERY) - (and (eq (cdr (assq 'erc-receive-query-display action)) 'PRIVMSG) - (member (erc-default-target) '("bob" "alice"))))) - -(defun my-erc-disp-chan-p (_ action) - (or (assq 'erc-autojoin-mode action) - (and (eq (cdr (assq 'erc-buffer-display action)) 'JOIN) - (member (erc-default-target) '("#emacs" "#fsf"))))) -@end lisp - -@noindent -You'll notice we ignore the @var{buffer} parameter of these predicates -because ERC ensures that @var{buffer} is already current (which is why -we can freely call @code{erc-default-target}). Note also that we -cheat a little by treating the @var{action} parameter like an alist -when it's really a cons of one or more functions and an alist. - -@noindent -To complement our predicates, we set all three buffer-display options -referenced in their @var{action}-alist lookups to -@code{display-buffer}. This tells ERC to defer to that function in -the display contexts covered by these options. - -@lisp -(setopt erc-buffer-display #'display-buffer - erc-interactive-display #'display-buffer - erc-receive-query-display #'display-buffer - ;; - erc-auto-reconnect-display 'bury) -@end lisp - -@noindent -The last option above just tells ERC to avoid any buffer-display -machinery when auto-reconnecting. (For historical reasons, ERC's -buffer-display options use the term ``bury'' to mean ``ignore'' rather -than @code{bury-buffer}.) - -Finally, we compose our predicates into @code{buffer-match-p} -conditions and pair them with various well known @code{display-buffer} -action functions and action-alist members. - -@lisp -(setopt display-buffer-alist - - ;; Create new frame with M-x erc-tls RET or (erc-tls ...) - '(((and (major-mode . erc-mode) my-erc-disp-entry-p) - display-buffer-pop-up-frame - (reusable-frames . visible)) - - ;; Show important chans and queries in a split. - ((and (major-mode . erc-mode) - (or my-erc-disp-chan-p my-erc-disp-query-p)) - display-buffer-pop-up-window) - - ;; Ignore everything else. - ((major-mode . erc-mode) - display-buffer-no-window - (allow-no-window . t)))) -@end lisp - -@noindent -Of course, we could just as well set our buffer-display options to one -or more homespun functions instead of bothering with -@code{display-buffer-alist} at all (in what would make for a more -complicated version of our first example). But perhaps we already -have a growing menagerie of similar predicates and like to keep -everything in one place in our @file{init.el}. - -@subsubheading Action alist items - -@table @asis -@item Option-based keys: -All keys are symbols, as are values, unless otherwise noted. - -@itemize @bullet -@item @code{erc-buffer-display} -@itemize @minus -@item @samp{JOIN} -@item @samp{NOTICE} -@item @samp{PRIVMSG} -@item @samp{erc} (entry point called non-interactively) -@item @samp{erc-tls} -@end itemize - -@item @code{erc-interactive-display} -@itemize @minus -@item @samp{/QUERY} -@item @samp{/JOIN} -@item @samp{/RECONNECT} -@item @samp{url} (hyperlink clicked) -@item @samp{erc} (entry point called interactively) -@item @samp{erc-tls} -@end itemize - -@item @code{erc-receive-query-display} -@itemize @minus -@item @samp{NOTICE} -@item @samp{PRIVMSG} -@end itemize - -@item @code{erc-auto-reconnect-display} -@itemize @minus -@item something non-@code{nil} -@end itemize -@end itemize - -@item Module-based (minor-mode) keys: - -@itemize @bullet -@item @code{erc-autojoin-mode} -@itemize @minus -@item channel name as a string, e.g., @code{"#chan"} -@end itemize -@end itemize -@end table - -@node Options -@section Options -@cindex options - -@c PRE5_4: (Node) Document every ERC option (module options go in -@c previous chapter) - -This section is extremely incomplete. For now, the easiest way to -check out all the available options for ERC is to do -@kbd{M-x customize-group @key{RET} erc @key{RET}}. - -@defopt erc-hide-list -If non, @code{nil}, this is a list of IRC message types to hide, e.g.: - -@example -(setq erc-hide-list '("JOIN" "PART" "QUIT")) -@end example -@end defopt - -@defopt erc-network-hide-list -If non, @code{nil}, this is a list of IRC networks and message types -to hide, e.g.: - -@example -(setq erc-network-hide-list (("Libera.Chat" "JOIN" "PART" "QUIT") -("OFTC" "JOIN" "PART"")) -@end example -@end defopt - -@defopt erc-channel-hide-list -If non, @code{nil}, this is a list of IRC channels and message types -to hide, e.g.: - -@example -(setq erc-channel-hide-list (("#erc" "JOIN" "PART" "QUIT") -("#emacs" "NICK")) -@end example -@end defopt - -@defopt erc-lurker-hide-list -Like @code{erc-hide-list}, but only applies to messages sent by -lurkers. The function @code{erc-lurker-p} determines whether a given -nickname is considered a lurker. -@end defopt - -@node Getting Help and Reporting Bugs -@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{https://www.emacswiki.org/emacs/ERC} is the -emacswiki.org page for ERC@. Anyone may add tips, hints, etc.@: to it. -If you do so, please help keep it up to date. - -@item -You can ask questions about using ERC on the Emacs mailing list, -@uref{https://lists.gnu.org/mailman/listinfo/help-gnu-emacs}, as well -as on ERC's own low-volume list, -@uref{https://lists.gnu.org/mailman/listinfo/emacs-erc}. - -@item -You can visit the IRC Libera.Chat channel @samp{#emacs}. Many of the -contributors are frequently around and willing to answer your -questions. You can also try the relatively quiet @samp{#erc}, on the -same network, for more involved questions. - -@item -@anchor{Upgrading} -You can check GNU ELPA between Emacs releases to see if a newer -version is available that might contain a fix for your issue: -@uref{https://elpa.gnu.org/packages/erc.html}. - -To upgrade, run @kbd{M-x list-packages @key{RET}}. In the -@file{*Packages*} (@code{package-menu-mode}) buffer, click the -@samp{erc} package link for the desired version. If unsure, or if the -version column is too narrow to tell, try the bottom-most candidate. -In the resulting @code{help-mode} buffer, confirm the version and -click @samp{Install}. Make sure to restart Emacs before reconnecting -to IRC, and don't forget that you can roll back to the previous -version by running @kbd{M-x package-delete @key{RET}}. -@xref{Packages,,,emacs, The Emacs Editor}, for more information. - -Note that a bug affecting Emacs's packaging machinery may prevent the -above method from working on Emacs versions 29 and below. Users on 29 -can try running @kbd{C-u M-x package-install @key{RET}} instead. -Users on 28 and below can click on the @emph{installed} @samp{erc} -line item in the @file{*Packages*} buffer instead of the newest one, -and then, in the resulting @code{help-mode} buffer, find and activate -the button for the newest version, which should appear in the summary -item @samp{Other versions}. - -In the rare instance you need an emergency fix or have volunteered to -test an edge feature between ERC releases, you can try adding -@samp{("devel" . "https://elpa.gnu.org/devel/")} to -@code{package-archives} prior to performing the steps above. For -this, you'll want to instead select a @dfn{snapshot} version from the -menu. Please be aware that when going this route, the latest changes -may not yet be available and you run the risk of incurring other bugs -and encountering unstable features. - -@item -To report a bug in ERC, use @kbd{M-x erc-bug}. - -@end itemize - - -@node History -@chapter History -@cindex history, of ERC - -@c abel@@bfr.co.il, sergey.berezin@@cs.cmu.edu -ERC was originally written by Alexander L. Belikoff and Sergey Berezin. -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 - -@c mlang@@delysid.org, alex@@gnu.org -In June 2001, Mario Lang and Alex Schroeder -took over development and created a ERC Project at -@uref{https://sourceforge.net/projects/erc}. - -In reaction to a mail about the new ERC development effort, 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 happened on @samp{#emacs} on -irc.openprojects.net. Over time, many people contributed code, ideas, -bugfixes, and a lot of alpha/beta/gamma testing. - -See the @file{CREDITS} file for a list of contributors. - -@item 2003 - -ERC 3.0 was released. - -@item 2004 - -ERC 4.0 was released. - -@item 2005 - -@c mwolson@@gnu.org -ERC 5.0 was released. Michael Olson became -the release manager and eventually the maintainer. - -After some discussion between him and the Emacs developers, it was -decided to include ERC in Emacs. - -@item 2006 - -ERC 5.1 was released. It was subsequently included in Emacs 22. - -ERC became an official GNU project, and development moved to -@uref{https://sv.gnu.org/projects/erc}. We switched to using GNU Arch as -our revision control system. Our mailing list address changed as well. - -@item 2007 - -We switched to using git for our version control system. - -@item 2009+ - -Since about 2009, ERC is no longer developed as a separate project, but -is maintained as part of Emacs. - -@end itemize - -@anchor{Official IRC channels} -@subheading Official IRC channels -@cindex official IRC channels - -The official channels for GNU Emacs and ERC lived on the Freenode IRC -network until June 2021, when they---along with the official IRC -channels of the GNU Project, the Free Software Foundation, and many -other free software communities---relocated to the Libera.Chat network -in the aftermath of changes in governance and policies of Freenode in -May and June 2021. GNU and FSF's announcements about this are at -@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html}, -@uref{https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html}, -and -@uref{https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html}. - -@node GNU Free Documentation License -@appendix GNU Free Documentation License -@include doclicense.texi - -@node Concept Index -@unnumbered Index - -@printindex cp - -@bye diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS deleted file mode 100644 index dd960994b4f..00000000000 --- a/etc/ERC-NEWS +++ /dev/null @@ -1,2551 +0,0 @@ -ERC NEWS - -Copyright (C) 2006-2025 Free Software Foundation, Inc. -See the end of the file for license conditions. - -Please send ERC bug reports to 'bug-gnu-emacs@gnu.org', -and Cc the 'emacs-erc@gnu.org' mailing list as well. -If possible, use 'M-x erc-bug' or 'M-x report-emacs-bug'. - -This file is about changes in ERC, the powerful, modular, and -extensible IRC (Internet Relay Chat) client distributed with -GNU Emacs since Emacs version 22.1. - - -* Changes in ERC 5.6.1 - -** Option 'erc-truncate-padding-size' controls truncation frequency. -In fast-moving channels and in queries with long-winded bots, the -'truncate' module has historically been asked to work overtime, mostly -on account of a rather stingy buffering threshold of 512 characters. -Now configurable, its default has been relaxed eightfold to 4096. - -** Option 'erc-modules' no longer autoloaded. -This cornerstone of ERC's configuration system was autoloaded globally -in 5.6 to allow users the freedom of running 'customize-option' without -first having to load the package. Unfortunately, this also had the side -effect of arranging for ERC to load on startup whenever someone -customized the variable. - -** New option determines 'keep-place-indicator's influence on 'truncate'. -Option 'erc-keep-place-indicator-truncation' manages the tension between -truncation and place keeping, prioritizing one or the other. - -** Stray key binding removed from 'erc-fill-wrap-mode-map'. -The command 'erc-fill-wrap-cycle-visual-movement' was mistakenly given -the key binding "C-c a" in an inadvertent holdover from development. It -has been removed. - -** Updated defaults for the 'track' module's face-list options. -The default values of options 'erc-track-faces-priority-list' and -'erc-track-faces-normal-list' have both gained a face for buttonized -speaker names, with the latter option also gaining 'erc-notice-face'. -This was done to provide a more frequent and practical indication of -channel activity in keeping with the module's original design. - -** Command 'erc-track-clear' resets the mode-line activity indicator. -Clear ERC's mode-line area with a single stroke, effectively marking all -ERC buffers as having been read. - -** An arguably less distracting 'erc-nicks-track-faces' variant. -Setting this option to t tells the 'track' module to have the mode-line -indicator stick with the most recent speaker's face, even when they're -monologuing, instead of alternating between it and the highest ranked -'erc-track-faces-normal-list' member in a given message. - -** Module 'querypoll' has left 'goodies' and moved in with 'notify'. -The 'querypoll' module was initially placed in 'erc-goodies' even though -a far more sensible home existed in 'erc-notify'. Given the similarity -of concerns and the newer module's "experimental" status, the migration -was deemed worth any potential disruption, despite this being a point -release. ERC appreciates your understanding in this matter. - -** Option 'erc-server-reconnect-function' has a new default. -ERC 5.6 added 'erc-server-delayed-check-reconnect', whose "probing" -strategy worked better for most users. While compatibility concerns -prevented it from becoming the new 'erc-server-reconnect-function' -outright, a new solution has emerged that defers to it when sensible. - -** Entry-point command 'erc-tls' once again considers option 'erc-port'. -In its zeal to enforce a preference for TLS connections, ERC 5.5 went a -bit far in disregarding the useful user option 'erc-port'. When called -from Lisp code without a ':port' keyword, 'erc-tls' once again respects -the option. - -** Changes in the library API. - -*** Reliable library access for ban lists. -Say goodbye to continually running "/BANLIST" for programmatic -purposes. Modules can instead use the function 'erc-sync-banlist' to -guarantee that the variable 'erc-channel-banlist' remains synced for -the remainder of an IRC session. - -*** Function 'erc-normalize-port' may return 0 instead of nil. -When given a nonempty, non-numeric string, this function now returns 0. -Moreover, ERC officially requests that users not use its output for -anything but comparing port equality, which was always its intended -purpose. - -*** Function 'erc-compute-port' no longer uses 'erc-normalize-port'. -An uninformed change in ERC 5.5 led to 'erc-compute-port' filtering its -result through 'erc-normalize-port', which brought unwelcome type -coercion and possible null return values. This defied its purpose of -ensuring a usable port. Users reliant on the aberrant 5.5 behavior -should wrap its return value in 'erc-normalize-port'. - -*** Local variable 'erc-session-port' may be a string. -Although this has always been the case, string values are now more -likely to be seen because ERC no longer coerces service names to port -numbers. - -*** The 'spelling' module makes better use of Flyspell's API. -As a consequence, the library functions 'erc-spelling-flyspell-verify' -and 'erc-spelling-unhighlight-word' are now unused and have been marked -obsolete. - - -* Changes in ERC 5.6 - -** Module 'keep-place' has a more decorative cousin. -Remember your place in ERC buffers a bit more easily with the help of -a configurable, visible indicator. Optionally sync the indicator to -any progress made while you haven't yet caught up to the live stream. -See options 'erc-keep-place-indicator-style' and friends, and try M-x -keep-place-indicator-mode to see it in action. - -** Module 'fill' offers an adaptive style based on 'visual-line-mode'. -This style dynamically wraps messages to a window's width while -mimicking the "hanging indent" look of 'erc-fill-static'. It also -provides some movement and editing commands to optionally tame the -less familiar aspects of 'visual-line' behavior. An interactive -helper called 'erc-fill-wrap-nudge' makes easy work of adjusting the -overhang on the fly. Set 'erc-fill-function' to 'erc-fill-wrap' to -get started. - -** A module for nickname highlighting has joined ERC. -Automatic nickname coloring has come to ERC core. Users familiar with -'erc-hl-nicks', from which this module directly descends, will already -be familiar with its suite of handy options. By default, each -nickname in an ERC session receives a unique face with a unique (or -uniformly dealt) foreground color. Add 'nicks' to 'erc-modules' to -get started. - -** A unified interactive entry point. -New users are often dismayed to discover that M-x ERC doesn't connect -to its default network, Libera.Chat, over TLS. Though perhaps a -decade overdue, this is no longer the case. Other UX improvements in -this area aim to make the process of connecting interactively slightly -more streamlined and less repetitive, even for veteran users. - -** Revised buffer-display handling. -A point of friction for new users and one only just introduced with -ERC 5.5 has been the lack of visual feedback when first connecting via -M-x erc or when issuing a "/JOIN" command at the prompt. As explained -below, in the news for 5.5, the discovery of a security issue led to -most new ERC buffers being "buried" on creation. On further -reflection, this was judged to have been an overcorrection in the case -of interactive invocations, hence the borrowing of an old option, -'erc-query-display', and the bestowing of a new alias, -'erc-interactive-display', which better describes its expanded role as -a more general buffer-display knob for interactive commands ("/QUERY" -still among them). - -Accompanying this addition are "display"-suffixed aliases for related -options 'erc-join-buffer' and 'erc-auto-query', which users have -reported as being difficult to discover and remember. When the latter -option (now known as 'erc-receive-query-display') is nil, ERC uses -'erc-join-buffer' in its place, much like it does for -'erc-interactive-display'. The old nil behavior can still be gotten -via the new compatibility flag 'erc-receive-query-display-defer'. The -relatively new option 'erc-reconnect-display' has likewise been -renamed, this time for clarity, to 'erc-auto-reconnect-display'. - -This release also introduces a few subtleties affecting the display of -new or reassociated buffers. One involves buffers that already occupy -the selected window. ERC now treats these as deserving of an implicit -'bury'. An escape hatch for this and most other baked-in behaviors is -now available in the form of a new type variant recognized by all such -options. That is, users can now specify their own function to -exercise full control over nearly all buffer-display related -decisions. See the newly expanded doc strings of 'erc-buffer-display' -and friends, as well as Info node '(erc) display-buffer', for details. - -** Setting a module's mode variable via Customize earns a warning. -Trying and failing to activate a module via its minor mode's Custom -widget has been an age-old annoyance for new users. Previously -ineffective, this method now actually works, but it also admonishes -users to edit the 'erc-modules' widget instead. - -** ERC's status-sidebar has gained an accompanying module. -Users can now add 'bufbar' to 'erc-modules' to achieve the same effect -as toggling 'erc-status-sidebar-open' manually at the start of an IRC -session. The module has also been outfitted to show channels and -queries under their servers by default. To avoid confusion, the major -mode for the actual sidebar buffer itself, 'erc-status-sidebar-mode', -is no longer available interactively. - -** A new spin on a classic integration in erc-speedbar. -Add 'nickbar' to 'erc-modules' to spawn a dynamically updating side -window listing all the users in any target buffer. It's powered by -the same speedbar.el integration you've always known, except this -one's optionally accessible from the keyboard, just like any other -side window. Hit '' over a nick to spawn a "/QUERY" or a -"Lastlog" (Occur) session. See 'erc-nickbar-mode' for more. - -** New 'querypoll' module for tracking non-channel query participants. -ERC has gotten a bit pickier about managing participants in query -buffers. "Untracked" correspondents no longer appear automatically in -membership tables, even if you respond or initiate contact. Instead, -ERC only adds and removes participant data when these same users join -and leave channels. Anyone uncomfortable with the apparent -uncertainty this brings can look to the new 'querypoll' module, which -periodically sends WHO requests to keep track of correspondents. -Those familiar with the IRCv3 Monitor extension can think of this as -"fallback code" and a temporary placeholder for the real thing. -Add 'querypoll' (and 'nickbar') to 'erc-modules' to try it out. - -** Option 'erc-timestamp-use-align-to' made more versatile. -While this option has always offered to right-align stamps via the -'display' text property, it's now more effective at doing so when set -to a number indicating an offset from the right edge. Users of the -'log' module may want to customize 'erc-log-filter-function' to -'erc-stamp-prefix-log-filter' to avoid ragged right-hand stamps -appearing in their saved logs. - -** Awkward entry point 'erc-server-select' improved but deprecated. -The alternate entry point 'erc-server-select' has mainly served to -confuse users in more recent years because it requires certain -options, like 'erc-nick', to be configured ahead of time, and it -doesn't support TLS. Its main selling point, historically, has been -interactive completion based on the option 'erc-server-alist', which -is a table of networks, servers, and ports. But most of the option's -400-odd entries are sadly defunct or otherwise outdated. And, these -days, most networks promote a well known load-balancing end point over -individual servers anyway. Regardless, the command has now been -improved to prompt for the same slate of parameters sought by -'erc-tls'. Similarly, 'erc-server-alist' entries now support a fifth -member in TLS ports (though this option too has been deprecated). If -you feel these deprecations rash or unwarranted, please file a bug -report and petition the maintainers for a reprieve. - -** Smarter reconnect handling for users on the move. -ERC now offers a new, experimental reconnect strategy in the function -'erc-server-delayed-check-reconnect', which tests for underlying -connectivity before attempting to reconnect in earnest. See option -'erc-server-reconnect-function' and new local module 'services-regain' -(also experimental) to get started. - -** Module-based keybinding adjustments for major modes. -To put it another way, simply loading a built-in module's library no -longer modifies 'erc-mode-map'. Instead, modifications occur during -module setup. This should not impact most user configs since ERC -doesn't bother with keys already taken and only removes bindings it's -previously created. Note that while all affected bindings still -reside in 'erc-mode-map', future built-in modules will use their own -minor-mode maps, and new third-party modules should do the same. - -** Option 'erc-timestamp-format-right' deprecated. -Having to account for this option prevented other ERC modules from -easily determining what right-sided stamps would look like before -insertion, which is knowledge needed for certain UI decisions. The -way ERC has chosen to address this is imperfect and boils down to -asking users who've customized this option to switch to -'erc-timestamp-format' instead. If you're affected by this and feel -that some other solution, like automatic migration, is justified, -please make that known on the bug list. - -** Module 'command-indicator' revives echoing, replacing 'noncommands'. -Command-line echoing has returned to ERC after a near decade-long -hiatus. This means you can elect to have ERC leave a trail of (most) -slash-command input submitted at the prompt, in a manner resembling -that of a shell or a REPL. The particulars are likely of little -interest to most users, but the gist is that this functionality was -removed in 5.3.x (Emacs 24.5) without mention in this document or a -change log. Everything's mostly been restored, except that the -feature is now opt-in. The only real gotcha is that related faces and -options, like 'erc-command-indicator', have moved to the 'erc-goodies' -library, although their Custom groups remain the same. Add -'command-indicator' to 'erc-modules' to get started. - -** Option 'erc-track-faces-normal-list' slightly more influential. -This option has always been a source of confusion for users, mainly -because its influence rode heavily on the makeup of faces in a given -message. Historically, when a buffer's current mode-line face was a -member of this option's value, ERC would only swap it out for a fellow -"normal" if it was absent from the message being processed. Beginning -with this release, ERC now looks to other ranked and, if necessary, -unranked "normals" instead of sustaining the same face between -messages. This was done to better honor the stated purpose of the -option, which is to provide consistent visual feedback when buffer -activity occurs. If you experience problems with this development, -see the compatibility flag 'erc-track-ignore-normal-contenders-p'. - -** 'erc-button-alist' and 'erc-nick-popup-alist' have evolved slightly. -It's no secret that the 'buttons' module treats potential nicknames -specially. This is perhaps most evident in its treatment of the -'nicknames' entry in 'erc-button-alist'. Indeed, to simplify ERC's -move to next-gen "rich UI" extensions, this special treatment is being -canonized. From here on out, this entry will no longer appear in the -option's default value but will instead be applied implicitly so long -as the option 'erc-button-buttonize-nicks' is non-nil, which it is by -default. Relatedly, the option 'erc-nick-popup-alist' now favors -functions, which ERC calls non-interactively, over arbitrary -s-expressions, which ERC will continue to honor. Although the default -lineup remains functionally equivalent, its members have all been -updated accordingly. - -** A slimmed down 'erc-track-faces-priority-list'. -This option, along with 'erc-track-faces-normal-list', has been purged -of certain 'button'-related face combinations. Originally added in -ERC 5.3, these combinations described the effect of "buttonizing" atop -faces added by the 'match' module, like '(erc-nick-default-face -erc-pal-face)'. However, since at least Emacs 27, 'match' has run -before 'button' in 'erc-insert-modify-hook', meaning such permutations -aren't possible. - -More importantly, users who've customized either of these options -should update them with the new default value of the option -'erc-button-nickname-face'. Like 'erc-nick-default-face', which it -replaces, the new 'erc-button-nick-default-face' is also a "real" -face. Its sole reason for existing is to make it easier for users and -modules to distinguish between basic buttonized faces and -'erc-nick-default-face', which is now reserved to mean the base -"speaker" face. - -** Option 'erc-query-on-unjoined-chan-privmsg' restored and renamed. -This option was accidentally removed from the default client in ERC -5.5 and was thus prevented from influencing PRIVMSG routing. It's now -been restored with a slightly revised role contingent on a few -assumptions explained in its doc string. For clarity, it has been -renamed 'erc-ensure-target-buffer-on-privmsg'. - -** A smarter, more responsive prompt. -ERC's prompt can be told to respond dynamically to incoming and -outgoing messages by leveraging the familiar function variant of the -option 'erc-prompt'. With this release, only predefined functions can -take full advantage of this new dynamism, but an interface to empower -third parties with the same possibilities may follow suit. To get -started, customize 'erc-prompt' to 'erc-prompt-format', and see the -option of the same name ('erc-prompt-format') for a rudimentary -templating facility reminiscent of 'erc-mode-line-format'. - -** Module 'scrolltobottom' now optionally more aggressive. -Enabling the experimental option 'erc-scrolltobottom-all' makes ERC -more vigilant about staking down the input area in all ERC windows. -And the option's 'relaxed' variant makes ERC's prompt stationary -wherever it happens to reside instead of forcing it to the bottom of a -window, meaning new input appears above the prompt, scrolling existing -messages upward to compensate. - -** Subtle changes for two fundamental faces. -Users of the default theme may notice that 'erc-action-face' and -'erc-notice-face' now appear slightly less bold. This improves button -detection and spares users from having to tweak faces (or options, -like 'erc-notice-highlight-type') just to achieve this effect. The -change is currently most noticeable in "/ME" messages, where -'erc-action-face' appears beneath 'erc-input-face' and -'erc-my-nick-face'. - -** Fewer nick buttons in QUIT, JOIN, and PART messages. -Common messages that show a nickname followed by a "userhost" often -end up with redundant buttons because the nick reappears in or is the -same as the "~user" portion. ERC now tamps down on this to make -ing around more convenient. To opt out, see the new variable -'erc-button-highlight-nick-once'. - -** Improved interplay between buffer truncation and message logging. -While most of these improvements are subtle, some affect everyday use. -For example, users of the 'truncate' module may notice that truncation -now happens between messages rather than arbitrary lines. And those -with the default 'erc-insert-timestamp-left-and-right' for their -'erc-insert-timestamp-function' will see date stamps reprinted after -every "/CLEAR" but omitted from any logs. One notable casualty of -these changes has been the deprecation of the ancient option -'erc-truncate-buffer-on-save'. Users of the 'log' module can achieve -the same effect by issuing a "/CLEAR" at the prompt. - -** The 'truncate' module no longer enables logging automatically. -Users expecting 'truncate' to perform logging based on the option -'erc-enable-logging' need to instead add 'log' to 'erc-modules' for -continued integration. Under the original design, merely loading the -library 'erc-log' caused 'truncate' to start writing logs, possibly -against a user's wishes. - -** The function 'erc-echo-timestamp' is now a command. -The option 'erc-echo-timestamps' (plural) has always enabled the -contextual printing of timestamps to the echo area when moving between -messages in an ERC buffer. Similar functionality is now available on -demand by invoking the newly interactive function 'erc-echo-timestamp' -atop any message. The new companion option 'erc-echo-timestamp-zone' -determines the default timezone when not specified with a prefix -argument. - -** Option 'erc-remove-parsed-property' deprecated. -This option's nil behavior serves no practical purpose yet has the -potential to degrade the user experience by competing for space with -forthcoming features powered by next generation extensions. Anyone -with a legitimate use for this option likely also possesses the -knowledge to rig up a suitable analog with minimal effort. That said, -the road to removal is long. - -** The 'track' module always ignores date stamps. -Users of the stamp module who leave 'erc-insert-timestamp-function' -set to its default of 'erc-insert-timestamp-left-and-right' will find -that date stamps no longer affect the mode line, even for IRC commands -not included in 'erc-track-exclude-types'. - -** Option 'erc-warn-about-blank-lines' is more informative. -Enabled by default, this option now produces more useful feedback -whenever ERC rejects prompt input containing whitespace-only lines. -When paired with option 'erc-send-whitespace-lines', ERC echoes a -tally of blank lines padded and trailing blanks culled. - -** A context-dependent mode segment in header and mode lines. -The "%m" specifier has traditionally expanded to a lone "+" in server -and query buffers and a string containing all switch modes (plus -"limit" and "key" args) in channel buffers. It now becomes a string -of user modes in server buffers and disappears completely in query -buffers. In channels, it's grown to include all letters and their -possibly truncated arguments, with the exception of stateful list -modes, like "b". - -** In-buffer "status messages" are now a thing. -The ancient option 'erc-ensure-target-buffer-on-privmsg' has been -repurposed slightly to express a third state denoted by the symbol -'status'. It tells ERC to revert to the old default behavior in which -separate, "pseudo" target buffers for status-prefixed conversing -co-existed alongside actual target buffers. Instead of this awkward -arrangement, ERC now acts like other clients by default and inserts -so-called "status messages" in situ, right between other messages. -Similar insertion-routing behavior now also applies to CTCP ACTIONs -directed at status-prefixed channels. Unfortunately, outgoing "/msg -@#chan hi" messages aren't yet shown in the same fashion, but the -groundwork has been laid, making such an addition almost trivial. - -** An easier way to see channel-membership prefixes on speakers. -The option 'erc-format-@nick' has been deprecated in favor of the new -boolean option 'erc-show-speaker-membership-status', a simple switch -to enable the displaying of status prefixes on the speaker nicks of -incoming chat messages. Prefixes on your speaker nick for outgoing -chat messages continue to always be present. - -** Updating user options requires cycling associated minor modes. -During a live ERC session, you may need to disable and re-enable a -module's minor mode via 'M-x erc-foo-mode RET' or similar before an -option's updated value takes effect. This primarily impacts new -options introduced by this release and existing ones whose behavior -has changed in some way. At present, ERC does not perform this step -automatically on your behalf, even if a change was made in a -'Custom-mode' buffer or via 'setopt'. - -** New broadcast-oriented slash commands /AME, /GME, and /GMSG. -Also available as the library functions 'erc-cmd-AME', 'erc-cmd-GME', -and 'erc-cmd-GMSG', these new slash commands can prove handy in test -environments. - -** New face 'erc-information' for local administrative messages. -Messages not originating from a server have historically been shown in -'erc-notice-face', sometimes in combination with 'erc-error-face'. -Neither are well suited for local messages of moderate importance. -From now on, such messages will appear in a more muted color but -retain the familiar 'erc-notice-prefix' stars. - -** Miscellaneous UX changes. -Some minor quality-of-life niceties have finally made their way to -ERC. For example, fool visibility has become togglable with the new -command 'erc-match-toggle-hidden-fools'. The 'button' module's -'erc-button-previous' command now moves to the beginning instead of -the end of buttons. A new command, 'erc-news', can be invoked to -visit this very file. And the 'irccontrols' module now supports -additional colors and special handling for "spoilers" (hidden text). - -** Changes in the library API. - -*** Some top-level dependencies have been removed. -The library 'erc-goodies' is no longer loaded by ERC's main library. -This was done to further cement the move toward a unidirectional -dependency flow begun in 5.5. Additionally, a few barely used and -newly introduced dependencies are now lazily loaded, which may upset -some third-party code. The first of these is 'pp' because its -'pp-to-string' is autoloaded in all supported ERC versions. Also gone -are 'thingatpt', 'time-date', and 'iso8601'. All were used ultra -sparingly, and the latter two have only been around for one minor -release cycle, so their removal hopefully won't cause much churn. - -*** Some ERC-applied text properties have changed. -Chiefly, a new set of metadata-oriented properties, the details of -which should be considered internal, now occupy the first character of -all inserted messages, including local notices, date stamps, and -interactive feedback. These properties will likely form the basis for -a new message-traversal/insertion/deletion API in future versions. -Less impactfully, the no-op property 'rear-sticky' has been removed, -and the value of the 'field' property for ERC's prompt has changed -from 't' to the more useful 'erc-prompt', although the property of the -same name has been retained and now has a value of 'hidden' when -disconnected. - -*** Flattened face lists for buttonized text. -Previously, when "buttonizing" a new region, ERC would combine faces -by blindly consing the new onto the existing. In theory, this kept a -nice record of all modifications to a given region. However, it also -complicated life for other modules wanting to analyze and operate on -these regions. Beginning with this release, ERC now merges combined -faces together when creating buttons, although the odd nested list may -still crop up here and there. - -*** Members of insert- and send-related hooks have been reordered. -As anyone reading this is no doubt aware, both built-in and -third-party modules rely on certain hooks for adjusting incoming and -outgoing messages upon insertion. And some modules only want to do so -after others have done their damage. Traditionally, this has required -various hacks and finagling to achieve. And while this release makes -an effort to load modules in a more consistent order, that alone isn't -enough to ensure predictability among essential members of important -hooks. - -Luckily, ERC now leverages a feature introduced in Emacs 27, "hook -depth," to secure the positions of a few key members of -'erc-insert-modify-hook' and 'erc-send-modify-hook'. So far, this -includes the functions 'erc-button-add-buttons', 'erc-match-message', -'erc-fill', and 'erc-add-timestamp', which now appear in that order, -when present, at depths beginning at 20 and ending below 80. Of most -interest to module authors is the new relative positioning of the -first three, which have been rotated leftward with respect to their -previous places in recent ERC versions (fill, button, match ,stamp). -A similar designated range from -80 to -20 also exists and is home to -the function 'erc-controls-highlight'. - -ERC also provisionally reserves the same depth intervals for -'erc-insert-pre-hook' and possibly other, similar hooks, but will -continue to modify non-ERC hooks locally whenever possible, especially -in new code. - -*** A singular entry point for inserting messages. -Displaying "local" messages, like help text and interactive-command -feedback, in ERC buffers has never been straightforward. As such, -ancient patterns, like the pairing of preformatted "notice" text with -ERC's oldest insertion function, 'erc-display-line', still appear -quite frequently in the wild despite having been largely phased out of -ERC's own code base in 2002. That this example has endured makes some -sense because it's probably seen as less cumbersome than fiddling with -the more powerful and complicated 'erc-display-message'. - -The latest twist in this tale comes with this release, for which a -healthy helping of "pre-insertion" business has permanently ensconced -itself in none other than 'erc-display-message'. While this would -seem to put antiquated patterns, like the above mentioned -'erc-make-notice' combo, at risk of having messages ignored or subject -to degraded treatment by built-in modules, an adaptive measure has -been introduced that recasts 'erc-display-line' as a thin wrapper -around 'erc-display-message'. And though nothing of the sort has been -done for the lower-level 'erc-display-line-1' (now an obsolete alias -for 'erc-insert-line'), some last-ditch fallback code has been -introduced to guarantee baseline functionality. As always, if you -find these developments disturbing, please say so on the tracker. - -*** ERC now manages timestamp-related properties a bit differently. -For starters, the 'cursor-sensor-functions' text property is absent by -default unless the option 'erc-echo-timestamps' is already enabled on -module init. And when present, the property's value no longer -contains unique closures and thus no longer proves effective for -traversing inserted messages. For now, ERC only provides an internal -means of visiting messages, but a public interface is forthcoming. -Also affecting the 'stamp' module is the deprecation of the function -'erc-insert-aligned' and its removal from the default client's code. -In the same library, the function 'erc-munge-invisibility-spec' has -been renamed to 'erc-stamp--manage-local-options-state' to better -reflect its purpose. Additionally, the module now merges its -'invisible' property with existing ones and includes all white space -around stamps when doing so. - -This "propertizing" of surrounding white space extends to all -'stamp'-applied properties, like 'field', in all intervening space -between message text and timestamps. Technically, this constitutes a -breaking change from the perspective of detecting a timestamp's -bounds. However, ERC has always propertized leading space before -right-sided stamps on the same line as message text but not before -those folded onto the next line. Such inconsistency made stamp -detection overly complex and produced uneven results when toggling -stamp visibility. - -*** Invisible message insertions not automatically made 'intangible'. -Previously, when 'erc-display-message' and friends spotted the -'invisible' text property with a value of t anywhere in text to be -inserted, it would apply that property to the entire message, along -with a t-valued 'intangible' property. Beginning with ERC 5.6, users -expecting this behavior will have to instead perform the treatment -themselves. To help with the transition, a temporary escape hatch has -been made available to regain this behavior, but its existence is only -guaranteed for this one minor version alone. See source code in the -vicinity of 'erc-insert-line' for more. - -*** Date stamps have become independent messages. -ERC now inserts "date stamps" generated from the option -'erc-timestamp-format-left' as separate, standalone messages. This -currently only matters if 'erc-insert-timestamp-function' is set to -its default value of 'erc-insert-timestamp-left-and-right', however -plans exist to decouple these features. In any case, ERC's near-term -UI goals require exposing these stamps to existing code designed to -operate on complete messages. For example, users likely expect date -stamps to be togglable with 'erc-toggle-timestamps' while also being -immune to hiding from commands like 'erc-match-toggle-hidden-fools'. -Before this change, meeting such expectations demanded brittle -heuristics that checked for the presence of these stamps in the -leading portion of message bodies as well as special casing to act on -these areas without inflicting collateral damage. - -Despite the rationale, this move admittedly ushers in a heightened -potential for disruption because third-party members of ERC's -modification hooks may not take kindly to encountering stamp-only -messages or the new behavior of 'erc-timestamp-last-inserted-left', -which no longer records the final trailing newline in the variable -'erc-timestamp-format-left'. If these inconveniences prove too -encumbering to deal with right away, see the escape hatch -'erc-stamp-prepend-date-stamps-p', which should help ease the -transition. As for detecting these new stamp-only messages from -members of 'erc-insert-modify-hook' and friends, see the function -'erc-stamp-inserting-date-stamp-p'. - -*** The role of a module's Custom group is now more clearly defined. -Associating built-in modules with Custom groups and "provided" library -features has improved. More specifically, a module's group now enjoys -the singular purpose of determining where the module's minor mode -variable lives in the Customize interface. And although ERC is now -slightly more adept at linking these entities, third-parties are still -encouraged to keep a module's name aligned with its group's as well as -the provided feature of its containing library, if only for the usual -reasons of namespace hygiene and discoverability. - -*** The function 'erc-open' no longer uses the 'TGT-LIST' parameter. -ERC has always used the parameter to initialize the local variable -'erc-default-recipients', which stores a list of routing targets with -the topmost considered "active." However, since at least ERC 5.1, a -buffer and its active target effectively mate for life, making -'TGT-LIST', in practice, a read-only list of a single target. And -because that target must also appear as the 'CHANNEL' parameter, -'TGT-LIST' mainly serves to reinforce 'erc-open's reputation of being -unruly. - -*** ERC supports arbitrary CHANTYPES. -Specifically, channels can be prefixed with any predesignated -character, mainly to afford more flexibility to specialty services, -like bridges to other protocols. - -*** 'erc-cmd-HELP' recognizes subcommands. -Some IRC "slash" commands are hierarchical and require users to -specify a subcommand to actually carry out anything of consequence. -Built-in modules can now provide more detailed help for a particular -subcommand by telling ERC to defer to a specialized handler. This -facility can be opened up to third parties should any one request it. - -*** Message-formatting templates in 'notify' renamed. -All templates beginning with the prefix "erc-message-english-notify_" -have been renamed to begin with "erc-message-english-notify-". For -example, the variable 'erc-message-english-notify_current' is now -'erc-message-english-notify_current'. The old names have been -preserved as obsolete aliases. - -*** Longtime quasi modules made proper. -The 'fill' module is now defined by 'define-erc-module'. The same -goes for ERC's imenu integration, which has 'imenu' now appearing in -the default value of 'erc-modules'. - -*** Function 'erc-get-user-mode-prefix' renamed. -This utility has been renamed to 'erc-get-channel-membership-prefix' -to better reflect its role of delivering a formatted "status prefix", -like "+" (for "voice"), and to avoid confusion with user modes, like -"+i" (for "invisible"). Additionally, its lone parameter is now -overloaded to accept an 'erc-channel-user' object as well as a string. - -*** Channel-membership table 'erc-channel-users' renamed. -Distinguishing between 'erc-channel-user' objects and values of the -'erc-channel-users' (plural) hash-table has been a constant source of -confusion, even within ERC's own code base. The hash-table's values -are cons cells whose CDR slot is an 'erc-channel-user'. To help keep -things sane, 'erc-channel-users' (plural) is now officially being -redubbed 'erc-channel-members'. Similarly, the utility function -'erc-get-channel-user' has been renamed to 'erc-get-channel-member'. -Expect deprecations of the old names to follow in a future release. - -*** Query participant tables now depend on channel membership. -ERC has always been inconsistent and difficult to predict in its -handling of records describing other IRC users. This has made simple -things like detecting the online status of query peers and the -presence of one's own user in 'erc-server-users' especially -unreliable. From now on, ERC resolves to be more sensible and -conservative in such areas. For example, it now retains its own user -info, once discovered, for the remainder of a session. It also relies -solely on channel membership to "drive" query participant information. -That is, when another IRC user departs their last known channel, any -queries with them will consider them absent, even if they're likely -still online. Anyone with difficulty adapting to this new paradigm -should contact the mailing list to inquire about associated -compatibility flags, which can be made public on request. Also see -the related news item announcing the module 'querypoll'. - -*** The 'erc-channel-user' struct has a changed internally. -The five boolean slots for membership prefixes have been folded -("encoded") into a single integer slot. However, the old 'setf'-able -accessors remain available, and the constructor's signature remains -unchanged. Since third-party code must be recompiled when upgrading -ERC anyway, users shouldn't experience any churn. The only caveat is -that third-party code using the literal read-syntax of these objects, -for example, in unit tests, will have to be updated. - -*** Hidden messages contain a preceding rather than trailing newline. -ERC has traditionally only offered to hide messages involving fools, -but plans are to make hiding more powerful. Anyone depending on the -existing behavior should be aware that hidden messages now start and -end one character earlier, so that hidden line endings precede rather -than follow accompanying text. However, an escape hatch is available -in the variable 'erc-legacy-invisible-bounds-p'. It reinstates the -old behavior, which is unsupported by newer modules and features. - -*** 'erc-display-message' optionally combines faces. -Users may notice that ERC now inserts some important error messages in -a combination of 'erc-error-face' and 'erc-notice-face'. This is -merely a consequence of 'erc-display-message' getting smarter about -how it treats face properties when its 'type' parameter is a list that -starts with t. Originally, ERC's authors intended to display both -server-originating and ERC-generated errors in this style, but that -intent was never realized. Though now possible, the effect has been -limited to special errors involving usage and internal state. For -third-party code, the key takeaway is that more 'font-lock-face' -properties encountered in the wild may be combinations of faces rather -than lone ones. - -*** 'erc-flood-protect' no longer influences input splitting. -This variable's role has been narrowed to rate limiting only. ERC -used to suppress protocol line-splitting when its value was nil, but -that's now handled by setting 'erc-split-line-length' to zero. - -*** 'erc-pre-send-functions' visits prompt input post-split. -ERC now adjusts input lines to fall within allowed length limits -before showing hook members the result. For compatibility, -third-party code can request that the final input be adjusted again -prior to being sent. To facilitate this, the 'erc-input' object -shared among hook members has gained a 'refoldp' slot. See doc string -for details. - -*** More flexibility in sending and displaying prompt input. -The abnormal hook 'erc-pre-send-functions' previously married outgoing -message text to its inserted representation in an ERC target buffer. -Going forward, users can populate the new slot 'substxt' with -alternate text to insert in place of the 'string' slot's contents, -which ERC still sends to the server. This dichotomy lets users -completely avoid the often fiddly 'erc-send-modify-hook' and friends -for use cases like language translation and subprotocol encoding. - -*** ERC's prompt survives the insertion of user input and messages. -Previously, ERC's prompt and its input marker disappeared while -running hooks during message insertion, and the position of its -"insert marker" (ERC's per-buffer process mark) was inconsistent -during these spells. To make insertion handling more predictable in -preparation for incorporating various protocol extensions, the prompt -and its bounding markers have become perennial fixtures. - -To effect this change, small behavioral differences in message -insertion have been adopted. Crucially, 'erc-insert-marker' now has -an "insertion type" of t, and 'erc-display-line-1' now calls 'insert' -instead of 'insert-before-markers. This allows user code running on -'erc-insert-modify-hook' and 'erc-insert-post-hook' to leave its own -markers at the actual insertion point instead of resorting to -workarounds. Message insertion for outgoing messages, in -'erc-display-msg', remains as before. In rare cases, these changes -may mean third-party code needs tweaking, for example, requiring the -use of 'insert-before-markers' instead of 'insert'. As always, users -feeling unduly inconvenienced by these changes are encouraged to voice -their concerns on the bug list. - -*** Introducing new ways to detect ERC buffer types. -The old standby 'erc-default-target' has served ERC well for over two -decades. But a lesser known gotcha affecting its use has always -haunted an unlucky few, that is, the function has always returned -non-nil in "unjoined" channel buffers (those that the client has -parted with or been kicked from). While perhaps not itself a major -footgun, recessive pitfalls rooted in this subtlety continue to affect -dependent functions, like 'erc-get-buffer'. - -To discourage misuse of 'erc-default-target', ERC 5.6 offers an -alternative in the function 'erc-target', which is identical to the -former except for its disregard for "joinedness." As a related bonus, -the dependent function 'erc-server-buffer-p' is being rebranded as -'erc-server-or-unjoined-channel-buffer-p'. Unfortunately, this -release lacks a similar solution for detecting "joinedness" directly, -but users can turn to 'xor'-ing 'erc-default-target' and 'erc-target' -as a makeshift kludge. - -*** Function 'erc-kill-channel' renamed to 'erc-part-channel-on-kill'. -This function, which normally emits a 'PART' when ERC kills a channel -buffer, has been renamed for clarity. Moreover, this and all other -members of 'erc-kill-channel-hook' can now take comfort in knowing -that the killing of buffers done on behalf of the option -'erc-kill-buffer-on-part' has been made more detectable by the flag -'erc-killing-buffer-on-part-p'. - -*** Stricter and more predictable channel-mode handling. -ERC has always processed channel modes using "standardized" letters -and popular status prefixes. Starting with this release, ERC will -begin preferring advertised "CHANMODES" when interpreting letters and -their arguments. To facilitate this transition, the functions -'erc-set-modes', 'erc-parse-modes', and 'erc-update-modes', have all -been provisionally deprecated. Expect a new, replacement API for -handling specific "MODE" types and letters in coming releases. If -you'd like a say in shaping how this transpires, please share your -ideas and use cases on the tracker. - -*** A better way to define message-formatting templates. -The functions 'erc-define-catalog-entry' and 'erc-define-catalog' have -been deprecated in favor of 'erc-define-message-format-catalog', a new -macro for defining template "catalogs" at the top level of libraries. - -*** Interface for determining display names renamed. -The option 'erc-format-nick-function' has been renamed to -'erc-speaker-from-channel-member-function' to better reflect its -actual role. So too has the related function 'erc-format-nick', which -is now 'erc-determine-speaker-from user'. - -*** All default response handlers return nil. -Actually, this isn't yet true, but ERC is moving in this direction. -The goal is to guarantee that trailing members of response hooks, like -'erc-server-005-functions', have an opportunity to run after the -default handler. For now, certain default handlers that may have -previously returned non-nil, like 'erc-server-PONG' and -'erc-server-904', have been updated to return nil in all cases. - -*** A template-based approach to formatting inserted chat messages. -Predicting and influencing how ERC formats messages containing a -leading "" has never been straightforward. The characters -bracketing the speaker and the faces used for each component have -always been hard-coded, with 'erc-format-query-as-channel-p' being the -only knob of any consequence. With this release, ERC begins its -transition to a unified formatting paradigm that builds upon the -already familiar "language catalog" templating system. Using a -separate "speaker catalog" keyed by contextual symbols, like -'query-privmsg', ERC (and eventually everyone) will more easily be -able to influence how inserted messages take shape in buffers. - -As a consequence of this transition, the default client no longer -calls `erc-format-privmessage' to format speaker messages. See that -function's doc string for help adapting to the new system, but please -keep in mind that discussions are still ongoing regarding its eventual -public interface. As usual, anyone interested should get involved by -writing to the mailing list. - -*** New format templates for inserted CTCP ACTION messages. -In 5.5 and earlier, ERC displayed outgoing CTCP ACTION messages in -'erc-input-face' alone (before buttonizing). Incoming ACTION messages -mirrored this, except with 'erc-action-face' throughout. Going -forward, inserted outgoing "/ME" messages will also incorporate -'erc-action-face', only underneath 'erc-input-face', with -'erc-my-nick-face' sitting atop both in the leading "speaker" nickname -portion (again, pre-buttonizing). This new behavior sidesteps the -traditional format template 'erc-message-english-ACTION' from the -default "language catalog" in favor of an entry from the new internal -"speaker catalog". Users needing to access the old behavior can do so -by toggling a provided compatibility switch. See source code around -the function 'erc-send-action' for details. - -*** Miscellaneous changes. -In 'erc-button-alist', 'Info-goto-node' has been supplanted by plain -old 'info', and the "" entry has been removed because it was -more or less redundant. In all ERC buffers, the "" key is now -bound to a new command, 'erc-tab', that calls 'completion-at-point' -inside the input area and otherwise dispatches module-specific -commands, like 'erc-button-next'. - - -* Changes in ERC 5.5 - -** Smarter buffer naming for withstanding collisions. -ERC buffers now remain tied to their logical network contexts, even -while offline. These associations can survive regional server changes -and the intercession of proxies. As has long been practiced in other -areas of Emacs, "uniquified" buffer renaming prevents collisions -between buffers of different contexts. ERC's approach prioritizes -predictability over economy, favoring fully qualified suffixes without -elided or omitted components. Potential avenues for confusion remain -but will die out with the adoption of emerging protocol extensions. - -** Option 'erc-rename-buffers' deprecated. -The promises made by its old "on" state are now fully realized and -enabled permanently by default. Its old behavior when disabled has -been preserved and will remain available (with warnings) for years to -come. - -** Option 'erc-reuse-buffers' deprecated. -This ancient option has been a constant source of confusion, as -exhibited most recently when its "disabled" meaning was partially -inverted. Introduced in ERC 5.4 (Emacs 28.1), this regression saw -existing channel buffers transparently reassociated instead of created -anew. The pre-5.4 "disabled" behavior has been restored and will -remain accessible for the foreseeable future, warts and all (e.g., -with its often superfluous "/DIALED-HOST" suffixing always present). - -** The 'networks' module is now quasi-required. -The 'networks' module is now all but required for everyday interactive -use. A default member of 'erc-modules' since ERC 5.3, 'networks' has -grown increasingly integral to core client operations over the years. -From now on, only the most essential operations will be officially -supported in its absence, and users will see a warning upon invoking -an entry point, like 'erc-tls', when that's the case. - -On a related note, the function 'erc-network' now always returns -non-nil in buffers created by a successfully established IRC -connection, even after that connection has been closed. This was done -to aid the overall effort to improve buffer association. - -** Tighter auth-source integration. -The days of hit-and-miss auth-source queries are hopefully behind us. -With the overhaul of the services module temporarily shelved and the -transition to SASL-based authentication still underway, users may feel -left in the lurch to endure yet another release cycle of backtick -hell. For some, auth-source may provide a workaround in the form of -nonstandard server passwords. See the section entitled "auth-source" -in the Integrations chapter of ERC's manual. - -** Rudimentary SASL support has arrived. -A new module, 'erc-sasl', now ships with ERC. See Info node "(erc) -SASL" in the manual for details. - -** Username argument for entry-point commands. -Commands 'erc' and 'erc-tls' now accept a ':user' keyword argument, -which, when present, becomes the first argument passed to the "USER" -IRC command. The traditional way of setting this globally, via -'erc-email-userid', is still honored. - -** Changes to display options for new ERC buffers. -The default value for the option 'erc-join-buffer', which determines -how new buffers are displayed, has been changed to 'bury' for security -reasons. Although the old value of 'buffer' is still accessible, -along with its original behavior, users wanting a safer alternative -can now opt for an improved 'window-noselect' instead. It still -offers the same pronounced visual cue when connecting and joining but -now avoids any hijacking of the active window as well. - -Beyond this, additional flexibility is now available for controlling -the behavior of newly created target buffers during reconnection. -See the option 'erc-reconnect-display' for more. - -** Improved handling of multiline prompt input. -This means better detection and handling of intervening and trailing -blanks when 'erc-send-whitespace-lines' is active. New options have -also been added for warning when input spans multiple lines. Although -off by default, new users are encouraged to enable them. See options -'erc-inhibit-multiline-input' and 'erc-ask-about-multiline-input'. - -** URL handling has improved. -Clicking on 'irc://' and 'ircs://' links elsewhere in Emacs now does -the right thing most of the time. However, for security reasons, -users are now prompted to confirm connection parameters prior to lift -off. See the new '(erc) Integrations' section in the Info manual for -details. - -** ERC's major-mode hook now runs slightly later. -The function 'erc-open' now delays running 'erc-mode-hook' until ERC's -prompt and its bounding markers and many essential local variables -have been initialized. Those essentials include the familiar -'erc-default-recipients', 'erc-server-users', and 'erc-network', as -well as the various "session" variables, like 'erc-session-connector'. -ERC activates "local modules" immediately afterward, just before -running 'erc-connect-pre-hook', which is still useful for gaining a -full accounting of what's been set. - -In similar news, 'erc-open' no longer calls 'erc-update-modules'. -However, it still activates modules in a similar fashion, meaning, -among other things, global-module setup still occurs before major-mode -activation (something that's here to stay for compatibility reasons). - -** Miscellaneous behavioral changes impacting the user experience. -A bug has been fixed that saw prompts being mangled, doubled, or -erased in server buffers upon disconnection. Instead, input prompts -now collapse into an alternate form designated by the option -'erc-prompt-hidden'. Behavior differs for query and channel buffers -but can be fine-tuned via the repurposed, formerly abandoned option -'erc-hide-prompt'. - -Another fix-turned-feature involves certain commands provided by the -'erc-match' module, such as 'erc-add-keyword', 'erc-add-pal', and -others, which now optionally offer to 'regexp-quote' the current -input. The old behavior, if desired, can still be had via the new -option 'erc-match-quote-when-adding'. - -In 5.4, support for using network symbols as keys was added for -'erc-autojoin-channels-alist'. This has been extended to include -explicit symbols passed to 'erc-tls' and 'erc' as so-called -network-context identifiers via a new ':id' keyword. The latter -carries wider significance beyond autojoin and can be used for -unequivocally identifying a connection in a human-readable way. - -A number of UX-centric bug fixes accompany this release. For example, -spaces are now possible in server passwords, and users of the Soju -bouncer should no longer see outgoing messages pile up during periods -of heavy traffic. See the Emacs change log for the full complement. - -** Miscellaneous behavioral changes in the library API. -A number of core macros and other definitions have been moved to a new -file called erc-common.el. This was done to help mitigate various -complications arising from the mutual dependency between 'erc' and -'erc-backend'. - -Also on the maintainability front, ERC now relies on the Compat -library from GNU ELPA to supply forward compatibility shims for users -running older versions of Emacs. The required Compat version resides -atop ERC's main library file, in the 'Package-Requires' header. -Third-party modules should benefit automatically from its adoption. - -In an effort to help further tame ERC's complexity, the variable -'erc-default-recipients' is now expected to hold but a single target. -As a consequence, functions like 'erc-add-default-channel' that -imagine an alternate, aspirational model of buffer-target relations -have been deprecated. For specifics, see entries in Emacs' -ChangeLog.4 from around June 30, 2022. - -A number of less consequential deprecations also debut in this -release. For example, the function 'erc-auto-query' was deemed too -difficult to understand, behavior wise, and has thus been stricken -from the client code path with no public replacement. Although likely -uncontroversial, such changes may still spell disruption for some. If -you find yourself among them and in need of explanations, please see -related entries in the change log and discussions on the bug tracker. - -Although this release is light on API features, some groundwork has -been laid for what may become a new breed of ERC module, namely, -"connection-local" (or simply "local") modules. This marks a small -but crucial step forward toward a more flexible and granular revamping -of ERC's long touted extensibility. See the Info node "(erc) Local -Modules" for details. - -Lastly, a few internal variables have been introduced that could just -as well have been made public, possibly as user options. Likewise for -some internal functions. As always, users needing such functionality -officially exposed are encouraged to write to emacs-erc@gnu.org. - - -* Changes in ERC 5.4.1 - -** No user-visible changes since ERC 5.4, but a few tweaks in some ERC -file headers and the ERC manual in order to successfully build ERC for -GNU ELPA. (See below for the news item of ERC now being distributed -on GNU ELPA in addition to its continued inclusion in GNU Emacs core.) - - -* Changes in ERC 5.4 - -** Starting with Emacs 28.1 and ERC 5.4, ERC NEWS are added here again. -After ERC 5.3, since November 2012, ERC's NEWS items were added in the -main Emacs NEWS file, and users were referred to there. Now, starting -with Emacs 28.1 and ERC 5.4, which mark ERC's release to GNU ELPA, ERC -NEWS have been moved to this file again, so that we can include a NEWS -file consisting only of ERC changes in ERC's package on GNU ELPA. - -The NEWS entries for ERC changes in Emacs 28.1 have been moved from -the main Emacs NEWS file to here. For ERC NEWS entries corresponding -to Emacs versions before 28, to avoid modifying the NEWS file for all -of those releases, the ERC NEWS entries have only been copied below, -and the NEWS.* files were left intact. - -** ERC is now available on GNU ELPA. -Starting with ERC 5.4, in addition to being distributed with GNU Emacs -itself, ERC is also included in GNU ELPA, allowing users to enjoy the -improvements of newer ERC versions on older Emacs versions as well. - -ERC's package page on GNU ELPA: https://elpa.gnu.org/packages/erc.html - -** New option 'erc-rename-buffers'. - -** New faces 'erc-my-nick-prefix-face' and 'erc-nick-prefix-face'. - -** 'erc-format-@nick' displays all user modes instead of only op and voice. - -** The display of irc commands in the current buffer has been disabled. - -** 'erc-version' now follows the Emacs version. - -** ERC can now hide message types by network or channel. -'erc-hide-list' will hide all messages of the specified type, while -'erc-network-hide-list' and 'erc-channel-hide-list' will only hide the -specified message types for the respective specified targets. - -** Reconnection is now asynchronous. - -** Nick completion is now case-insensitive again after inadvertently -being made case-sensitive in Emacs 24.2. - -** New variable 'erc-default-port-tls' used to connect to TLS IRC -servers. - -** New hook 'erc-insert-done-hook'. -This hook is called after strings have been inserted into the buffer, -and is free to alter point and window configurations, as it's not -called from inside a 'save-excursion', as opposed to 'erc-insert-post-hook'. - -** 'erc-button-google-url' has been renamed to 'erc-button-search-url' -and its value has been changed to Duck Duck Go. - -** 'erc-send-pre-hook' and 'erc-send-this' have been obsoleted. -The user option to use instead to alter text to be sent is now -'erc-pre-send-functions'. - -** Improve matching/highlighting of nicknames. -Open and close parenthesis and apostrophe are not considered valid -nick characters anymore, matching the given grammar in RFC 2812 -section 2.3.1. This enables correct matching and highlighting of -nicks when they are surrounded by parentheses, like "(nick)", and when -adjacent to an apostrophe, like "nick's". - -** Set 'erc-button-url-regexp' to 'browse-url-button-regexp' -which better handles surrounding pair of parentheses. - -** New function 'erc-switch-to-buffer-other-window' -which is like 'erc-switch-to-buffer', but opens the buffer in another -window. - -** New function 'erc-track-switch-buffer-other-window' -which is like 'erc-track-switch-buffer', but opens the buffer in -another window. - -** NickServ passwords can now be retrieved from auth-source. -The 'erc-use-auth-source-for-nickserv-password' user option enables -querying auth-source for NickServ passwords. To enable this, add the -following to your init file: - - (setq erc-use-auth-source-for-nickserv-password t) - -** NickServ identification now prompts for password last. -When 'erc-prompt-for-nickserv-password' is non-nil, the user used to -be unconditionally prompted interactively for a password, regardless -of the value of 'erc-nickserv-passwords', which was effectively -ignored (same for the new -'erc-use-auth-source-for-nickserv-password'). This limitation is now -lifted, and the user is interactively prompted last, after the other -identification methods have run. - -** The '/ignore' command will now ask for a timeout to stop ignoring the user. -Allowed inputs are seconds or ISO8601-like periods like "1h" or "4h30m". - -** ERC now recognizes 'C-]' for italic text. -Italic text is displayed in the new 'erc-italic-face'. - -** erc-match.el now supports 'message' highlight type (not including the nick). -The 'erc-current-nick-highlight-type', 'erc-pal-highlight-type', -'erc-fool-highlight-type', 'erc-keyword-highlight-type', and -'erc-dangerous-host-highlight-type' user options now support a -'message' type for highlighting the entire message but not the -sender's nick. - -** erc-status-sidebar.el is now part of ERC. -The 'erc-status-sidebar' package which provides a HexChat-like -activity overview sidebar for joined IRC channels is now part of ERC. - -** erc-tls now supports specifying a TLS client certificate. -The 'erc-tls' function has been updated to allow specifying a TLS -client certificate for authentication, as an alternative to NickServ -password-based authentication. This is referred to as "CertFP" (short -for Certificate Fingerprint) by several IRC networks. See the Info -node "(erc) Connecting" in the ERC manual for more details and -examples on how to specify and use TLS client certificates with -'erc-tls'. - -** Update IRC-related references to point to Libera.Chat. -The Free Software Foundation and the GNU Project have moved their -official IRC channels from the Freenode network to Libera.Chat. -For the original announcement and the follow-up update, including -more details, see: - -https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00005.html -https://lists.gnu.org/archive/html/info-gnu/2021-06/msg00007.html - -Given the relocation of GNU and FSF's official IRC channels, as well -as #emacs and various other Emacs-themed channels (see the link below) -to Libera.Chat, IRC-related references in the Emacs repository have -now been updated to point to Libera.Chat. - -https://lists.gnu.org/archive/html/info-gnu-emacs/2021-06/msg00000.html - -** Add 'erc-track-select-mode-line-face' (obsoletes 'erc-track-find-face'). -The 'erc-track-find-face' function of the erc-track module has been -declared obsolete and rewritten as 'erc-track-select-mode-line-face', -with different expected arguments (the current and old faces are now -separated) and clearer documentation. - -** Add '/opme' and '/deopme' convenience commands. -The new '/opme' convenience command asks ChanServ to set the operator -status for the current nick in the current channel, and '/deopme' -unsets it. - -** Add '/wii' convenience command for whois with idle time. -The new '/wii' convenience command calls the '/whois' command with the -given nick as both arguments, which is useful for displaying the whois -information for the nick along with idle time, even if the nick is on -a different server than the one the current user is connected to. -Using the given nick itself instead of the server it is connected to -is not standardized, but is widely supported across IRC networks. - -** Add 'erc-bug' command for reporting ERC bugs. -The new 'erc-bug' command prompts for a subject, and passes it on to -'report-emacs-bug' along with the current ERC version, and adds the -ERC mailing list in Cc. - - -* Changes in ERC 5.3 - -** New function `erc-tls' is to be used for connecting to a server via TLS. -It requires the tls.el library. - -** The function `erc-ssl' will now always use ssl.el, even in the version -of ERC that comes with Emacs. - -** Type `C-u' before `C-c C-j' to prompt for a channel key -`erc-join-channel' now accepts a prefix-argument to prompt for the key -when channels are protected by keywords. - -** ERC will now automatically determine which nick prefixes are valid -when joining a server. - -** Figure out which directory contains startup files when looking for -.erc.el. For Emacs this is usually ~/.emacs.d, and for XEmacs this is -usually ~/.xemacs. - -** Fix bug with view-mode when running erc-toggle-debug-irc-protocol. - -** Permit several commands to be run even when the server connection is dead. -This includes /CLEAR, /COUNTRY, /HELP, /LASTLOG, /QUIT, /GQUIT, -/RECONNECT, /SERVER, and /SET. - -** Make /RECONNECT work better when the server connection is dead. -Also, handle case where the server buffer has been killed. - -** Better handle interaction with /RECONNECT and indefinite reconnect -attempts. Display message which tells the user that they can stop the -reconnect attempts by killing the server buffer. - -** New option `erc-reuse-frames' determines whether new frames are always -created. It defaults to not creating a new frame for an ERC buffer if -there is already a window displaying it. This only has an effect when -the `erc-join-buffer' option is set to 'frame. - -** New command /ME'S handles the case where someone types "/me's" in an -ERC buffer. It concatenates the text " 's" to the beginning of the -input and then sends the result like a normal /ME command. - -** Fix bug where some messages were being sent to the server too soon. -In the past, this may have resulted in strange problems like seeing -the connection attempt stall, which may have especially affected -spotty or traffic-shaped connections. - -** Handle 307 (nick has identified) responses from the server. - -** Display a less-confusing message if the connection attempt fails. - -** On a tty, make sure that notices are displayed in blue rather than pink. - -** By default, open query buffers that are initiated by others in a new -unselected window. This may be changed by customizing the -`erc-auto-query' option. This should make ERC more friendly to new -users. - -** New option `erc-query-display' indicates how to display a query buffer -that is made using the /QUERY command. The default is to display the -query in a new selected window. - -** By default, display network name rather than server name in the modeline. -This should ERC use less space in the modeline. To get the old -behavior back, set `erc-mode-line-format' to "%s %a". - -** New option `erc-remove-parsed-property' determines whether to remove -the 'erc-parsed property. This should save some memory in channels -with large amounts of text on screen. It is enabled by default. - -** Modules newly enabled by default - -*** move-to-prompt: Move to the prompt when typing text. -*** networks: Provide data about IRC networks. - -** New formatting variables allowed in `erc-format-network': - -*** `%N': the name of the network. -*** `%S': much like %s, but let the network name trump the server name. - -** Compatibility with old releases - -*** In `erc-server-coding-system' and `erc-coding-system-for-target', pass -the `target' argument as the first and only argument to the function -named by these options. - -*** In `erc-track-faces-priority-list', permit list entries to be lists of -faces. This can be used to differentiate between, for example, -buttons in default text and buttons in notices. - -*** The `erc-assert' function has been removed in favor of using `assert' -from cl-macs.el. - -*** If your application uses the 'erc-parsed text property outside of -the insert hooks, you will need to set `erc-remove-parsed-property' -to nil. - -** Changes and additions to modules - -*** BBDB (erc-bbdb.el) - -**** Work around bug in XEmacs 21.4 that causes an error to be thrown when -the first argument to `run-at-time' is nil. - -*** Button (erc-button.el) - -**** Recognize parentheses that are part of URLs. - -**** When in a channel, only buttonize nicks from that channel. - -*** DCC support (erc-dcc.el) - -**** Turn this into the "dcc" module for ERC, so that it can be more -easily enabled. - -**** New option `erc-dcc-listen-host' determines which IP address to listen -on for outside connection attempts. - -**** New option `erc-dcc-public-host' determines which IP address to advertise -when sending a file. This is useful for people who are on a local -subnet. Together, these two options replace the `erc-dcc-host' -option. - -**** New option `erc-dcc-receive-cache' indicates how much of a received -file to store in an Emacs buffer before flushing it to disk. The -default is 0.5 MB. - -**** Save only parts of received files in buffers, writing repeatedly to -disk after we get at least `erc-dcc-receive-cache' bytes. This allows -users to receive very large files without running out of memory. - -**** Rename `erc-verbose-dcc' option to `erc-dcc-verbose' and also -default it to nil. - -**** Fix edge case in erc-dcc-send-sentinel. - -**** If client confirms too much, then display byte count and kill the -file buffer. - -*** Goodies (erc-goodies.el) - -**** New module move-to-prompt causes the point to be moved to the prompt -if a user tries to type elsewhere in the buffer, and then inserts -their keystrokes after the prompt. It is enabled by default. - -**** New module keep-place keeps your place in unvisited ERC buffers -when new messages arrive. - -**** Enable scroll-to-bottom in all ERC buffers when the module is enabled, -rather than having the user do it manually. - -**** Fix bug with buffer ordering and scroll-to-bottom module. - -**** In the unmorse module, handle the morse code style that has "/ " at -the end of every letter. - -*** Identd (erc-identd.el) - -**** Fix bad behavior when closing the identd process. - -*** Channel lists (erc-list.el) - -**** Replace the old module with a rewritten one, so that we can include -it with Emacs. The old version of erc-list.el has been renamed to -erc-list-old.el, and is available as the list-old module. - -The new version does not yet have support for XEmacs. - -**** Don't display lots of output in the server buffer when running /LIST. - -*** Logging (erc-log.el) - -**** Permit the `erc-log-channels-directory' option to be set to a function -name. This makes it easier to write custom functions that determine -where log files should be placed. - -**** New option `erc-log-filter-function' specifies the function to call -for filtering text before writing it to a log file. By default, no -filtering is performed. - -*** Networks (erc-networks.el) - -**** Turn this into the "networks" module for ERC, so that it can be more -easily enabled. Enable it by default. - -**** Add support for Rizon. - -*** Internet services / Nickserv (erc-services.el) - -**** New hook option `erc-nickserv-identified-hook' is run after NickServ -acknowledges a successful identification. - -**** Add support for the GRnet and Rizon networks. - -*** Timestamps (erc-stamp.el) - -**** By default, place timestamps on both the left and the right. -The left timestamps appear once a day, and the right timestamps appear -once a minute when new messages arrive. To change this, customize the -`erc-insert-timestamp-function' and -`erc-insert-away-timestamp-function' options. - -*** Channel tracking (erc-track.el) - -**** If `erc-track-position-in-mode-line' is set to nil, the tracking -information won't be shown in the mode line, which is a change from -the previous behavior of showing it "After all other information". - -If this variable is set to t, then the information will be added to -the very end of the mode line. - -**** New option `erc-track-remove-disconnected-buffers' controls whether -buffers associated with a server that is disconnected should be -removed from the modified buffers list. The default is to keep them -in the list. - -**** New hook option `erc-track-list-changed-hook' is run whenever the -contents of the modified channels list changes. It is useful for -people who use a separate mechanism to provide notification of channel -activity. - -**** The `erc-track-switch-direction' option now can be set to the value -'importance. If set to this value, ERC will switch to channels in -order of importance, which is determined by the position of the -channel's face in `erc-track-faces-priority-list'. - -**** Activate erc-track-minor-mode earlier in the connection process. - -**** Don't track buttons in notices. - -**** Get a rough idea for which channels are currently active by -switching between several normal conversation faces in the modeline. -This behavior can be modified by changing the new -`erc-track-faces-normal-list' option. - -**** Ignore display of who set the default channel topic and listing of -users on the current channel. Customize the `erc-track-exclude-types' -option to indicate the types of messages to exclude. These two -message types are "333" and "353", respectively. - -*** Support for acting as an XDCC file-server (erc-xdcc.el) - -**** Turn this into the "xdcc" module for ERC, so that it can be more -easily enabled. - - -* Changes in ERC 5.2 - -** M-x erc RET now starts ERC. -`erc-select' has been changed to `erc'. `erc-select' still remains as -an alias of `erc'. Likewise, `erc-select-ssl' has been renamed to -`erc-ssl' with `erc-select-ssl' as its alias. The function that was -known as `erc' is now `erc-open'. - -** Open query buffers by default when private messages are received. -The default value of `erc-auto-query' has been changed to 'bury. - -** New command: /RECONNECT -This command tries to reconnect to the current IRC server exactly -once. It does not work in server buffers (throws an error before the -command is run), but works in query and channel buffers. - -** In MS-DOS environments, look for _ercrc.el rather than .ercrc.el. - -** Fix buggy interaction with multi-tty Emacs. - -** After running /QUIT, make sure that the IRC process is killed within -4 seconds. Freenode, in particular, needs this at times. - -** If the IRC process has not responded to our PINGs within a certain -time, kill it and restart the connection. See -`erc-server-auto-reconnect', `erc-server-reconnect-attempts', -`erc-server-reconnect-timeout', `erc-server-send-ping-interval', and -`erc-server-send-ping-timeout' to fine-tune ERC's behavior. - -** Avoid getting into an infinite connection loop. -Previously, this could happen if your nick was banned, you were using -Tor, incorrect information was entered, or the connection was bad. - -** Make ban messages less confusing. - -** Restore the point correctly when reconnecting to an IRC server. - -** Make /IGNORE and /UNIGNORE prompt to determine whether their -argument is a user or a regexp. This results in less-confusing -behavior when trying to ignore someone who has a bracket in their -nick. - -** Make the default port "6667" rather than "ircd", because some -operating systems don't know what port "ircd" maps to. - -** Fix several bugs in erc-iswitchb (C-c C-b). - -** Clean up internal documentation. -Special thanks go to Juanma Barranquero for the thorough vetting of -ERC's internal documentation. - -** Display a more informative message when a module is not found. - -** Fix a bug where paths were being colored like IRC commands. - -** In the customize interface for `erc-modules', add the name of the module. -This makes it easier to find modules by name. - -** erc-server-send-ping-interval: Change to use a default of 30 seconds. - -** Some files which are included with the release of ERC 5.2 will not -appear in the version of ERC that is bundled with Emacs 22. These -extras files may be found at: - - o https://ftp.gnu.org/gnu/erc/erc-5.2-extras.tar.gz, or - o https://ftp.gnu.org/gnu/erc/erc-5.2-extras.zip. - -** Renamed files - -Several files were renamed so as to make them distinct to users of the -MS-DOS operating system. - - o erc-autojoin.el -> erc-join.el - o erc-complete.el -> erc-hecomplete.el - o erc-nickserv.el -> erc-services.el - o ChangeLog.NNNN -> ChangeLog.NN - -** Header line changes - -*** Remove "[IRC]" from the header line. - -*** Add the %l format character to `erc-header-line-format', - -*** Document how to remove the header line. -Namely: (setq erc-header-line-format nil). - -** New options - -*** erc-server-reconnect-attempts: Determines the number of -reconnection attempts that ERC will make per server. - -*** erc-server-reconnect-timeout: Determines the amount of time, -in seconds, that ERC will wait between successive reconnect attempts. - -*** erc-server-send-ping-timeout: Determines when to consider a connection -stalled and restart it. The default is after 120 seconds. - -*** erc-system-name: Determines the system name to use when logging in. -The default is to figure this out by calling `system-name'. - -** New face: `erc-my-nick-face' -This helps make it easier to distinguish messages sent by yourself -from messages sent by other users when the value of the variable -`erc-show-my-nick' is non-nil. - -** Namespace changes - -*** New macro: `erc-with-server-buffer' -Switches to the current ERC server buffer and runs some code. If no -server buffer is available, return nil. This is a useful way to -access variables in the server buffer. - -*** New function: `erc-open-server-buffer-p' -Returns non-nil if the given buffer is an ERC server buffer that has -an open IRC process. - -*** New function: `erc-format-lag-time' -Returns the estimated lag time to server, `erc-server-lag'. - -*** Renamed items - - o `erc-server-setup-periodical-server-ping' is now - `erc-server-setup-periodical-ping' - - o `erc-away-p' is now `erc-away-time' - -** Changes to the ERC manual - -*** New section: Sample Session. -Describes a sample ERC session for connecting to the #emacs channel on -Freenode. Also mention the #erc channel. - -*** New section: Special Features. -Describes some of the special features of ERC. - -*** Getting Started: Mention ~/.emacs.d/.ercrc.el and the Customize -interface. - -*** Development: Mention ErcDevelopment page on emacswiki.org. - -*** Tips and Tricks: Remove empty section for now. - -*** Options: Mention how to see available ERC options. - -*** Sample Configuration: Add an example of how to configure ERC. - -** New modules - -*** Autoaway (erc-autoaway.el) - -**** Make this much more reliable. - -**** Avoid duplicate messages when coming back from being away. - -**** Fix bug where autoaway was enabled just by loading the file. - -*** BBDB (erc-bbdb.el) - -**** Display information on how to cancel merging of info or how to -create a new John Doe record. - -**** Make it so that information from /whois continues to come in, even -while prompting for a record to merge. - -**** Make hitting C-g correctly abort merging the record. - -*** Capab identify (erc-capab.el) -Mark users who haven't identified to NickServ on servers supporting -CAPAB IDENTIFY-MSG. - -** Changes and additions to modules - -*** Button (erc-button.el) - -**** Make go to the previous button. - -*** Channel tracking (erc-track.el) - -**** Use mouse-face and help-echo for channel names in the mode-line. -This helps people using a mouse know that they are buttons and can be -clicked on. - -**** Fix issue where C-c C-SPC could conflict with user-defined keybindings. -This is accomplished by moving these bindings to their own global -minor mode. Now the default is to check whether the user has bound -something to C-c C-SPC or C-c C-@. If they have, prompt them about -whether to really override that binding. This also has the effect of -preventing ERC from clobbering rcirc's keybinding, unless this is -desired. See `erc-track-enable-keybindings' for more details. - -**** New option: erc-track-enable-keybindings. -Determine whether or not to enable the C-c C-SPC and C-c C-@ -keybindings. The default is to ask whether to do this if a binding to -these keys already exists. It can also be set to t or nil to always -bind or never bind, respectively. - -**** Remove `track-when-inactive' module. -See `erc-track-when-inactive' for further details. - -**** New option: erc-track-when-inactive. -This option replaces the track-when-inactive module. Set it to -non-nil to track activity even in visible buffers when inactive. The -default is nil. - -**** Remove the `track-modified-channels' alias for the `track' module. - -*** DCC support (erc-dcc.el) - -**** Add Usage section to Commentary. - -**** Fix a bug in the server message output. - -*** Filling (erc-fill.el) - -**** Fix bug involving messages that start with one or more blank lines. - -*** Identd (erc-identd.el) - -**** New option `erc-identd-port' -Specifies the port to use if none is given as an argument to -`erc-identd-start'. This is placed in the new customization group -`erc-identd'. - -**** New function: `erc-identd-quickstart' -Ignores any arguments and calls `erc-identd-start'. - -*** Channel lists (erc-list.el) - -**** Enable by default, except in the version of ERC bundled with Emacs 22. - -*** Logging (erc-log.el) - -**** Make sure filenames are safe to use before writing to them. - -**** Save all log buffers when exiting Emacs. - -**** erc-generate-log-file-name-function: Add option for -`erc-generate-log-file-name-network', which is a new function that -uses the network name rather than the server name when possible. - -*** Menu (erc-menu.el) - -**** Name the menu "ERC" instead of "IRC" to avoid confusion with rcirc -and other clients. - -**** Make this into a proper module and load it by default. - -**** Add "Current channel" submenu. - -*** Networks (erc-networks.el) - -**** Add support for Ars OpenIRC, LinuxChix, and OFTC networks. - -**** Escape periods in Konfido.Net and Kewl.Org. - -*** Internet services / Nickserv (erc-nickserv.el) - -**** Add new 'both method for the `erc-nickserv-identify-mode' option -and make it the default. This tries to do the right thing both when a -known nickserv message exists for an IRC network, and when it does -not. - -**** Support nickserv authentication on OFTC, Azzurra, Ars, and QuakeNet. - -**** Support authentication on BitlBee. - -**** Make source code easier to understand by using accessor functions. - -*** Sound support (erc-sound.el) - -**** Make this work with both Emacs 21 and Emacs 22. - -*** Timestamps (erc-stamp.el) - -**** Exclude the newline from the erc-timestamp field. - -**** New function: `erc-toggle-timestamps'. -Toggles display of timestamps. - - -* Changes in ERC 5.1.4 - -** Make find-function and find-variable work in Emacs 22 for -names that are constructed by `define-erc-module'. - -** Fix bug introduced in ERC 5.1.3 that caused messages to go the -wrong buffer. - -** Changes and additions to modules - -*** Highlighting (erc-match.el) - -**** Don't activate view-mode. - -*** Logging (erc-log.el) - -**** When this module is activated, make sure logging is enabled on -already-opened buffers. Ditto for disabling logging when the module -is deactivated. - -**** Fix some errors that occur when exiting Emacs without first -quitting open IRC servers. - - -* Changes in ERC 5.1.3 - -** Fix use of /quote command with no initial whitespace. - -** Make it possible to customize the colorization of the header line. -The `erc-header-line' face is used to color the header line. -The `erc-header-line-face-method' determines the method to use when -colorizing the header line. - -** Add the new function `erc-handle-irc-url', which is a suitable -candidate to use for `url-irc-function'. This permits some -integration of url.el and ERC. - -** Fix several errors that occur when server or channel buffers are killed -prematurely. - -** Fix toggling of flood control. - -** Match the patterns in `erc-encoding-coding-alist' as regexps, -instead of verbatim text. Also, match case-insensitively. - -** The /SMV command has been removed, since we no longer have -meaningful module-specific version information. - -** Fix a "(stringp nil)" error that can happen when doing /PART. - -** Use a better example in the `erc-part-reason-various-alist' -documentation. - -** When using `erc-quit-reason-various' and `erc-part-reason-various' -and no matches are found, default to using the ERC version string -rather than "nil". - -** Add the `list' and `page' modules to the `erc-modules' customize -interface. - -** Changes to the ERC manual - -*** Update the list of available modules. - -*** Revise information about releases and development. - -*** Provide a simpler example in the "Getting Started" chapter. - -*** Fully document how to connect to an IRC server in the new -"Connecting" chapter. - -** Changes and additions to modules - -*** Autoaway (erc-autoaway.el) - -**** Rename the `erc-autoaway-use-emacs-idle' option to -`erc-autoaway-idle-method'. - -**** Add support for autoaway based on user idle time. -This is now the default. - -**** If you set the AWAY status yourself, erc-autoaway will not -interfere by un-setting AWAY prematurely. - -**** If you are set away while visiting a non-ERC buffer, -erc-autoaway used to fail in bringing the user back. This is now -fixed. - -*** BBDB (erc-bbdb.el) - -**** Add new option `erc-bbdb-electric-p', which determines whether -to make the BBDB buffer electric. This defaults to not electric. - -*** Button (erc-button.el) - -**** Use instead of for `erc-button-previous'. - -*** Identd (erc-identd.el) - -**** Fix a bug that involves starting the identd server. - -**** Make this work with Emacs 22. - -**** Provide a real ERC module named `identd'. - -**** Don't create an extra buffer for the identd process. - -*** Channel lists (erc-list.el) - -**** Enable by default, except in the version of ERC bundled with Emacs 22. - -*** Logging (erc-log.el) - -**** By default, don't insert old logs when opening an ERC buffer. -This may be changed by customizing `erc-log-insert-log-on-open'. - -**** New option `erc-log-write-after-send' determines whether the -log file will be written to after every sent message. The default is -not to do this. - -**** New option `erc-log-write-after-insert' determines whether the -log file will be written to when new text is added to a logged ERC -buffer. The default is not to do this. With this option and the -previous option, logging should no longer slow down ERC as much. - -**** Default to saving buffers and queries on quit. -This may be changed by customizing the `erc-save-buffer-on-quit' and -`erc-save-queries-on-quit' options, respectively. - -**** Only perform logging when the `logging' module is added to -`erc-modules'. This prevents logging from being activated just by -loading the erc-log.el file, and makes logging act like other ERC -modules. - -*** Programmable completion (erc-pcomplete.el) - -**** Don't complete the user's current nickname. - - -* Changes in ERC 5.1.2 - -** Fix compiler errors in erc-autojoin.el and erc-dcc.el. - -** Move to end of prompt when ERC reconnects to a server. - -** Changes and additions to modules - -*** Spell-checking (erc-spelling.el) - -**** Don't spell-check nicks or words that are prefixed with '/'. - -**** Remove flyspell properties from words we shouldn't spell-check. - -**** Fix an issue that caused the ispell process to reload every time -we switch to an ERC buffer. - -*** Timestamps (erc-stamp.el) - -**** Fix an inconsistency in calculating width of right timestamps. - -**** Rename option `erc-timestamp-right-align-by-pixel' to -`erc-timestamp-use-align-to'. This controls whether to use the more -fail-proof method of aligning right timestamps, as mentioned below. - -**** Fix a right timestamp spacing problem that used to occur when -erc-stamp.el was byte-compiled. Now that this is fixed, it is safe to -use the method that aligns right timestamps perfectly in Emacs22 with -X. If the current version of Emacs doesn't support this method, use -the simpler method, which is prone to alignment issues for math -symbols and other variable-width text. - -A side effect of using this new method is that there will only be one -space before a right timestamp in any saved logs. If this is -unacceptable, set `erc-timestamp-use-align-to' to nil. - - -* Changes in ERC 5.1.1 - -** Fix a requirement on cl.el. - -** Use tls.el for SSL connections, rather than ssl.el. - -** Changes and additions to modules - -*** ibuffer integration (erc-ibuffer.el) - -**** Update this to work with the version of ibuffer.el that comes with -recent Emacs variants. - -*** Old completion (erc-complete.el) - -**** Fix a few errors. - -*** Speedbar (erc-speedbar.el) - -**** Make this work with the version of speedbar.el that comes with -recent Emacs variants. - -*** Timestamps (erc-stamp.el) - -**** By default, use a more failsafe method of displaying right timestamps. -To get right timestamps to align perfectly in Emacs22 using X, set the -new `erc-timestamp-right-align-by-pixel' option to non-nil. - -*** Viper compatibility (erc-viper.el) - -**** Since most of these changes are now merged into Emacs22, detect -whether we need these changes and install them only if necessary. - - -* Changes in ERC 5.1 - -** 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, reuse 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. - - -* Changes in ERC 5.0.4 - -** Fix a problem with undo in channels. - - -* Changes in ERC 5.0.3 - -** 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. - - -* Changes in ERC 5.0.2 - -** 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. - - -* Changes in ERC 5.0.1 - -** 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 in ERC 5.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 hash table, - `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 in ERC 4.0 - -** 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 initialization code a bit, if you - have some existing customizations. 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 in ERC 3.0.cvs.20030119 - -** 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 statements 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. - - ----------------------------------------------------------------------- -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 3 of the License, 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. If not, see . - - -Local variables: -coding: utf-8 -mode: outline -mode: emacs-news -paragraph-separate: "[ ]*$" -end: diff --git a/lisp/desktop.el b/lisp/desktop.el index 4fd01660c5d..95eb1376a42 100644 --- a/lisp/desktop.el +++ b/lisp/desktop.el @@ -539,7 +539,6 @@ can guess how to load the mode's definition.") (isearch-mode nil) (vc-mode nil) (vc-dir-mode nil) - (erc-track-minor-mode nil) (savehist-mode nil)) "Table mapping minor mode variables to minor mode functions. Each entry has the form (NAME RESTORE-FUNCTION). diff --git a/lisp/erc/ChangeLog.1 b/lisp/erc/ChangeLog.1 deleted file mode 100644 index 220ea2f09e6..00000000000 --- a/lisp/erc/ChangeLog.1 +++ /dev/null @@ -1,11726 +0,0 @@ -2008-11-19 Andy Stewart - - * erc.el (erc-header-line-uses-tabbar-p): New option that makes - tabbar mode usable with ERC if set to non-nil. - (erc-update-mode-line-buffer): Use it. - -2008-11-19 Glenn Morris - - * erc-compat.el (help-function-arglist): Autoload it. - -2008-10-03 Michael Olson - - * erc-dcc.el (english): Increase size heading by two places. - (erc-dcc-byte-count): Move higher. - (erc-dcc-do-LIST-command): Use erc-dcc-byte-count to get accurate - count. Coerce byte total to floating point before performing - computation, otherwise division will truncate to 0. - (erc-dcc-append-contents): Update erc-dcc-byte-count. - (erc-dcc-get-filter): Don't update erc-dcc-byte-count, because - that will give incorrect size totals. Instead, figure out how - much we have by summing byte count and current buffer size. - (erc-dcc-get-sentinel): Don't update erc-dcc-byte-count. - -2008-10-01 Michael Olson - - * erc-dcc.el (erc-pack-int): Make sure returned string is within 4 - bytes. Always return a 4-byte string, so that we conform to the - CTCP spec. - (erc-most-positive-int-bytes): New constant representing the - number of bytes that most-positive-fixnum can be stored in. - (erc-most-positive-int-msb): New constant representing the - contents of the most significant byte of most-positive-fixnum. - (erc-unpack-int): Make sure that the integer we get back can be - represented in Emacs. - (erc-dcc-do-CLOSE-command): Update docstring. Don't use the line - variable. Try to disambiguate between type and nick when only one - is provided. Validate both type and nick arguments. Allow - matching by just nick. - (erc-dcc-append-contents): Set inhibit-read-only to t. Prevent - auto-compression from triggering when we write the contents to a - file. - (erc-dcc-get-file): Prevent auto-compression from triggering when - we truncate a file. - -2008-07-27 Dan Nicolaescu - - * erc.el: Remove code for Carbon. - -2008-06-07 Glenn Morris - - * erc-autoaway.el, erc-ibuffer.el, erc-menu.el: - * erc-stamp.el, erc.el: Remove unnecessary eval-when-compiles. - -2008-05-30 Diane Murray - - * erc-backend.el (328): New response handler. - - * erc.el (english): Add 328 to catalog. - -2008-05-29 Diane Murray - - * erc-services.el (erc-nickserv-alist): Update REGEXP and - SUCCESS-REGEXP for freenode. - -2008-05-05 Juanma Barranquero - - * erc-goodies.el (erc-noncommands-list, noncommands) - (erc-control-characters, erc-interpret-controls-p) - (erc-interpret-mirc-color): Fix typos in docstrings. - (erc-controls-highlight): Reflow docstring. - -2008-04-26 Johan Bockgård - - * erc.el (erc-put-text-properties): Don't use mapcar*. - (erc-display-line-1): Fix argument order in call to - erc-put-text-properties. - -2008-04-14 Michael Olson - - * erc.el (erc-remove-text-properties-region): Disable this command - by default. Thanks to e1f for the suggestion. - -2008-02-20 Michael Olson - - * erc.el (erc-notice-face): Fix this face for Emacs 21 users. - -2008-02-05 Juanma Barranquero - - * erc.el (erc-valid-nick-regexp): - * erc-button.el (erc-button-syntax-table): - * erc-match.el (erc-match-syntax-table): Replace `legal' with `valid'. - -2008-02-04 Jeremy Maitin-Shepard - - * erc.el (erc-cmd-QUERY): Bind the value of `erc-auto-query' to - `erc-query-display' rather than `erc-join-buffer'. This fixes a - bug where the value of erc-auto-query was being ignored. - -2008-01-31 Michael Olson - - * erc-dcc.el (erc-dcc-do-GET-command, erc-dcc-do-SEND-command): - Improve docstring. If FILE argument is split into multiple - arguments, re-join them into a single string, separated by a - space. This fixes an issue where the user wants to send or - receive a file with spaces in its name. It is assumed that no one - will try sending or receiving a file with multiple consecutive - spaces in its name, otherwise this fix will fail. - - * erc.el (erc-mode-map): Add binding for C-c C-x to - erc-quit-server, since rcirc.el binds its quit command in a - similar manner. Thanks to Jari Aalto for the suggestion. - -2008-01-28 Diane Murray - - * erc-list-old.el (list-old): Define module as list-old, not list. - This fixes a bug where an unknown module error would occur when - starting ERC and using the list-old module. - - * erc-track.el (erc-track-find-face): If no choice was found - return nil to use the default mode-line faces. - -2008-01-26 Michael Olson - - * erc.el (erc-version-string): Release ERC 5.3. - - * Makefile (VERSION): Update. - (EXTRAS): Remove erc-list.el after all, because this is mainly for - users of the version that comes with Emacs, and they will have - erc-list.el by Emacs 23. - (MISC): Add ChangeLog.07. - (elpa): Fix build issue. Add proper version to erc-pkg.el. - - * README.extras: Mention Emacs 23. - - * erc-pkg.el: Make the version string a template. - - * erc.texi (Obtaining ERC): Update extras URLs for 5.3. - (Development): Write instructions for git, and remove those for Arch. - (History): Mention the switch to git. - -2008-01-25 Michael Olson - - * NEWS: Update. - - * erc-goodies.el (keep-place): New module which keeps your place - in unvisited ERC buffers when new messages arrive. This is mostly - taken from Johan Bockgård's init file. - (erc-noncommands-list): Move to correct place. - - * erc-networks.el: Add a module definition. - - * erc-services.el (erc-nickserv-identify-mode): Force-enable the - networks module, because we need it to set erc-network for us. - - * erc-track.el (erc-track-faces-normal-list): Indicate in the - docstring that this variable can be set to nil. - - * erc.el: On second thought, don't load erc-networks. Just enable - the networks module by default. - (erc-modules): Add option for keep-place and networks. Enable - networks by default. - (erc-version-string): Make release candidate 1 available. - -2008-01-24 Michael Olson - - * erc.el: Load erc-networks.el so that functions get access to the - `erc-network-name' function. - - * erc-track.el (erc-track-faces-normal-list): Add - erc-dangerous-host-face. - (erc-track-exclude-types): Add 333 and 353 to the default list of - things to ignore, and explain what they are in the docstring. - -2008-01-23 Michael Olson - - * erc-track.el (erc-track-faces-priority-list): Move - erc-nick-default-face higher, so that it can be used for the - activity indication effect. Add erc-current-nick-face, - erc-pal-face, erc-dangerous-host-face, and erc-fool-face by - themselves. - (erc-track-faces-normal-list): New option that contains a list of - faces to consider "normal". - (erc-track-position-in-mode-line): Minor docfix. - (erc-track-find-face): Use erc-track-faces-normal-list to produce - a sort of blinking activity effect. - -2008-01-22 Michael Olson - - * erc-button.el (erc-button-add-nickname-buttons): When in a - channel buffer, only look at nicks from the current channel. - Thanks to e1f for the report. - -2008-01-21 Michael Olson - - * erc-compat.el (erc-const-expr-p, erc-list*, erc-assert): Remove, - since we can use the default `assert' function without it causing - us any problems, even in Emacs 21. Thanks to bojohan for the - suggestion. - - * erc-goodies.el (move-to-prompt): Use the "XEmacs" method - instead, because the [remap ...] method interferes with - delete-selection-mode. - (erc-move-to-prompt): Rename from erc-move-to-prompt-xemacs. - Deactivate mark and call push-mark before moving point. Thanks to - bojohan for the suggestion. - (erc-move-to-prompt-setup): Rename from - erc-move-to-prompt-init-xemacs. - - * erc-track.el (erc-track-faces-priority-list): Replace erc-button - with '(erc-button erc-default-face) so that we only care about - buttons that are part of normal text. Adjust customization type - to handle this case. Make erc-nick-default-face a list. Handle - pals, fools, current nick, and dangerous hosts. - (erc-track-find-face): Simplify. Adapt for list of faces case. - (erc-faces-in): Don't deflate lists of faces. Add them as-is. - (erc-track-face-priority): Use equal instead of eq. - -2008-01-20 Michael Olson - - * erc-goodies.el (erc-move-to-prompt, erc-move-to-prompt-xemacs): - Fix off-by-one error that caused the point to move when placed at - the beginning of some already-typed text. Thanks to e1f for the - report. - - * erc-dcc.el, erc-xdcc.el: Add simple module definitions. - - * erc.el (erc-modules): Add dcc and xdcc. - -2008-01-19 Michael Olson - - * erc-bbdb.el (erc-bbdb-insinuate-and-show-entry): Work around bug - in XEmacs 21.4 that throws an error when the first argument to - run-at-time is nil. - - * erc-button.el (button): Undo XEmacs-specific change to all ERC - buffers when module is removed. - (erc-button-setup): Rename from erc-button-add-keys, and move - XEmacs-specific stuff here. - - * erc-goodies.el (erc-unmorse): Improve regexp for detecting - morse. Deal with the morse style that has "/ " at the end of - every letter. - (erc-imenu-setup): New function that sets up Imenu support. Add - it instead of a lambda form to erc-mode-hook. - (scrolltobottom): Remove erc-scroll-to-bottom from all ERC buffers - when module is removed. Activate the functionality in all ERC - buffers when the module is activated, rather than leaving it up to - the user. - (move-to-prompt): New module that moves to the ERC prompt if a - user tries to type elsewhere in the buffer, and then inserts their - keystrokes there. This is mostly taken from Johan Bockgård's init - file. - (erc-move-to-prompt): New function that implements this. - (erc-move-to-prompt-xemacs): New function that implements this for - XEmacs. - (erc-move-to-prompt-init-xemacs): New function to perform the - extra initialization step needed for XEmacs. - - * erc-page.el, erc-replace.el: Fix header and footer. - - * erc-track.el (erc-track-minor-mode-maybe): Take an optional - buffer arg so that we can put this in erc-connect-pre-hook. If - given this argument, include it in the check to determine whether - to activate erc-track-minor-mode. - (track): Add erc-track-minor-mode-maybe to erc-connect-pre-hook, - so that we can use it as soon as a connection is attempted. - - * erc.el (erc-format-network, erc-format-target-and/or-network): - Use erc-network-name function instead, and check to see whether - that function is bound. This fixes an error in process filter for - people who did not have erc-services or erc-networks loaded. - (erc-modules): Add move-to-prompt module and enable it by - default. Thanks to e1f for the suggestion. - -2008-01-18 Michael Olson - - * Makefile (EXTRAS): Include erc-list-old.el. - - * erc-dcc.el (erc-dcc-verbose): Rename from erc-verbose-dcc. - (erc-pack-int): Rewrite to not depend on a count argument. - (erc-unpack-int): Rewrite to remove 4-character limitation. - (erc-dcc-server): Call set-process-coding-system and - set-process-filter-multibyte so that the contents get sent out - without modification. - (erc-dcc-send-filter): Don't take a substring -- just pass the - whole string to erc-unpack-int. - (erc-dcc-receive-cache): New option that indicates the number of - bytes to let the receive buffer grow before flushing it. - (erc-dcc-file-name): New buffer-local variable to keep track of - the filename of the currently-received file. - (erc-dcc-get-file): Disable undo for a speed increase. Set - erc-dcc-file-name. Truncate the file before writing to it. - (erc-dcc-append-contents): New function to append the contents of - a buffer to a file and then erase the contents of the buffer. - (erc-dcc-get-filter): Flush buffer contents after exceeding - erc-dcc-receive-cache. This allows large files to be downloaded - without storing the whole thing in memory. - (erc-dcc-get-sentinel): Flush any remaining contents before - closing. No need to save buffer. - (erc-dcc-listen-host): New option that determines which IP address - to listen on. - (erc-dcc-public-host): New option that determines which IP address - to advertise when sending a file. This is useful for people who - are on a local subnet. Together, these two options replace - erc-dcc-host. - - * erc.el (erc-mode-line-format): Add %N and %S. %N is the name of - the network, and %S is much like %s but with the network name - trumping the server name. Default to "%S %a". Thanks to e1f for - the suggestion. - (erc-format-network): New function that formats the network name. - (erc-format-target-and/or-network): New function that formats both - the network name and target, falling back on the server name if - the network name is not available. - (erc-update-mode-line-buffer): Add the new format spec items. - -2008-01-17 Michael Olson - - * erc.el (erc-join-buffer): Improve documentation. - (erc-query-display): New option indicating how to display a query - buffer that is made by using the /QUERY command. The default is - to display the query in a new window. - (erc-cmd-QUERY): Use it. Improve docstring. - (erc-auto-query): Default this to 'window-noselect instead, - because I've already seen bug reports about new users thinking - that ERC didn't display their test messages. Improve - customization type. - (erc-notice-face): Make this work with XEmacs. - (erc-join-buffer): Mention 'buffer in docstring. Improve - customization type. - - * erc-dcc.el (erc-dcc-send-sentinel): Better handle case where elt - is nil, in order to avoid an error. Thanks to Brent Goodrick for - the initial patch. - (erc-dcc-display-send): New function split from erc-dcc-send-hook. - (erc-dcc-send-connect-hook): Use it -- we don't like lambda forms - in hooks. - (erc-dcc-send-filter): Display byte count if the client confirmed - too much, and kill the buffer. Otherwise a DoS might be possible - by making Emacs run out of RAM. - - * erc-backend.el (erc-server-connect): Detect early on whether the - connection attempt has failed in order to avoid confusing error - messages. - - * erc-networks.el (erc-server-alist): Add Rizon network. - - * erc-services.el (erc-nickserv-passwords): Add Rizon to options. - (erc-nickserv-alist): Add support for Rizon. - - * erc-track.el (erc-track-find-face): Don't let buttons in notices - trump default text. Use catch/throw. Default to first element of - FACES is nothing is found. - - * erc-xdcc.el: Add local variables for proper indentation setup. - -2008-01-15 Michael Olson - - * erc-backend.el (erc-server-coding-system): Docfix. - (erc-coding-system-for-target): Pass the `target' argument along - as the first and only argument. It's not good to just depend on a - dynamic binding. - -2008-01-10 Michael Olson - - * erc-backend.el (321, 322): Split message-displaying parts into - new functions, which are added to each response's respective - hook. This makes them easier to disable. - - * erc-list.el: New file from Tom Tromey. Use erc-propertize - instead of propertize. Require 'erc. - (list): New module definition. Remove message-displaying - functions for 321 and 322 response handlers when enabling the - module, and restore them when disabling. As a sanity check, - remove the erc-list-handle-322 function when disabling the module. - (erc-list-handle-322): Handle the case where we run the LIST - command, but do not go through the normal steps. - (erc-cmd-LIST): Add docstring. Strip initial space from line if - it is non-nil. Use make-local-variable to silence compiler - warning. Capture current buffer and pass it to - erc-list-install-322-handler. - (erc-list-install-322-handler): Take server-buffer argument, so - that we are certain of being in the right buffer. Use 4th - argument to add-hook, so that erc-server-322-functions is only - modified in one buffer. - - * erc-list-old.el: Renamed from old erc-list.el. - - * erc.el (erc-modules): Add list-old. - (erc-set-topic): Handle case where there are no newlines in the - existing topic, which happens when /LIST is run. - (erc-notice-face): If we have less than 88 colors, make this - blue. Otherwise the text will be pink in a tty, which looks - dreadful. Thanks to e1f for the report. - (erc-remove-parsed-property): New option that determines whether - to remove the erc-parsed property after displaying a message. - This should have the effect of making ERC take up less memory. - (erc-display-line-1): Use it. - -2008-01-04 Stefan Monnier - - * erc-ibuffer.el (erc-channel-modes): - Pass mode-name through format-mode-line - -2007-12-16 Diane Murray - - * erc-services.el (erc-nickserv-alist): Removed autodetect regexp, - added identified regexp for OFTC. - (erc-nickserv-identification-autodetect): Make sure success-regex - is non-nil. - (erc-nickserv-identify-autodetect): Make sure identify-regex is - non-nil. Doc fix. - -2007-12-13 Diane Murray - - * erc-backend.el (PRIVMSG, QUIT, TOPIC, WALLOPS, 376, 004, 221) - (312, 315, 319, 330, 331, 333, 367, 368, 391, 405, 406, 412) - (421, 432, 433, 437, 442, 461, 474, 477, 482, 431): Doc fix. - -2007-12-09 Michael Olson - - * erc-services.el (erc-nickserv-alist): Fix regexps for GRnet. - -2007-12-09 Giorgos Keramidas (tiny change) - - * erc-backend.el, erc.el: - Parse 275 (secure connection) responses. - - * erc-services.el: Add identification hooks for GRnet, the Greek - IRC network . - -2007-12-08 David Kastrup - - * erc-stamp.el (erc-echo-timestamp): - * erc-lang.el (language): - * erc-backend.el (erc-server-connect): Fix buggy call to `message'. - -2007-12-07 Theresa O'Connor - - * erc-services.el: Provide a hook that runs when nickserv confirms - that the user has successfully identified. - (services, erc-nickserv-identify-mode): Add and remove - erc-nickserv-identification-autodetect from - erc-server-NOTICE-functions. - (erc-nickserv-alist): Add SUCCESS-REGEXP to each entry. - (erc-nickserv-alist-identified-regexp) - (erc-nickserv-identification-autodetect): New functions. - (erc-nickserv-identified-hook): New hook. - -2007-12-06 Deepak Goel - - * erc-match.el (erc-add-entry-to-list): Fix buggy call to `error'. - -2007-12-01 Glenn Morris - - * erc-backend.el (erc-server-send-ping): Move after definition of - erc-server-send. - -2007-11-29 Giorgos Keramidas (tiny change) - - * erc-backend.el, erc.el: - Parse 307 (nick has identified) responses. - -2007-11-15 Juanma Barranquero - - * erc.el (erc-open): - * erc-backend.el (define-erc-response-handler): - * erc-log.el (log): - * erc-match.el (erc-log-matches): Fix typos in docstrings. - -2007-11-11 Michael Olson - - * erc-autoaway.el (erc-autoaway-possibly-set-away): - * erc-netsplit.el (erc-netsplit-timer): - * erc-notify.el (erc-notify-timer): - * erc-track.el (erc-user-is-active): Only run if we have - successfully established a connection to the server and have - logged in. I suspect that sending messages too soon may make some - IRC servers not respond well, particularly when the network - connection is iffy or subject to traffic-shaping. - -2007-11-01 Michael Olson - - * erc-compat.el (erc-set-write-file-functions): New compatibility - function to set the write hooks appropriately. - - * erc-log.el (erc-log-setup-logging): Use - erc-set-write-file-functions. This fixes a byte-compiler warning. - - * erc-stamp.el: Silence byte-compiler warning about - erc-fill-column. - - * erc.el (erc-with-all-buffers-of-server): Bind the result of - mapcar to a variable in order to silence a byte-compiler warning. - -2007-10-29 Michael Olson - - * erc-ibuffer.el (erc-modified-channels-alist): Use - eval-when-compile, and explain why we are doing this. - -2007-10-25 Dan Nicolaescu - - * erc-ibuffer.el (erc-modified-channels-alist): Pacify - byte-compiler. - -2007-10-13 Glenn Morris - - * erc-track.el (erc-modified-channels-update): Use mapc rather - than mapcar. - -2007-10-12 Diane Murray - - * erc.el (erc-join-channel): Prompt for channel key if C-u or - another prefix-arg was typed. - - * NEWS: Noted this change. - -2007-10-07 Michael Olson - - * erc.el (erc-cmd-ME'S): New command that handles the case where - someone types "/me's". It concatenates the text " 's" to the - beginning of the input and then sends the result like a normal - "/me" command. - (erc-command-regexp): Permit single-quote character. - -2007-09-30 Aidan Kehoe (tiny change) - - * erc-log.el (erc-save-buffer-in-logs): Prevent spurious warnings - when looking at a log file and concurrently saving to it. - -2007-09-18 Exal de Jesus Garcia Carrillo (tiny change) - - * erc.texi (Special-Features): Fix small typo. - -2007-09-16 Michael Olson - - * erc-track.el (erc-track-switch-direction): Mention - erc-track-faces-priority-list. Thanks to Leo for the suggestion. - -2007-09-11 Exal de Jesus Garcia Carrillo (tiny change) - - * erc-sound.el: Fix typo in setting up instructions. - -2007-09-10 Michael Olson - - * Makefile (elpa): Copy dir template rather than echoing a few - lines. The reason for this is that the ELPA package for ERC was - getting a corrupt dir entry. - - * dir-template: Template for the ELPA dir file. - -2007-09-08 Michael Olson - - * erc-log.el (erc-log-filter-function): New option that specifies - the function to call for filtering text before writing it to a log - file. Thanks to David O'Toole for the suggestion. - (erc-save-buffer-in-logs): Use erc-log-filter-function. Make sure - we carry along the value of coding-system-for-write, because this - could potentially be shadowed by the temporary buffer. - - * erc.el (erc-version-string): Update to 5.3, development version. - -2007-09-07 Glenn Morris - - * erc.el (erc-toggle-debug-irc-protocol): Fix call to - erc-view-mode-enter. - -2007-08-08 Glenn Morris - - * erc-log.el, erc.el: Replace `iff' in doc-strings and comments. - -2007-09-03 Michael Olson - - * erc.el (erc-default-port): Make this an integer value rather - than a string. Thanks to Luca Capello for the report. - -2007-08-27 Michael Olson - - * erc.el (erc-cmd-GQUIT): If erc-kill-queries-on-quit is non-nil, - kill all query buffers after 4 seconds. - -2007-08-16 Michael Olson - - * NEWS: Add ERC 5.3 changes section, and mention jbms' erc-track - compatibility note. - - * erc-track.el (erc-track-list-changed-hook): Turn this into a - customizable option. - (erc-track-switch-direction): Add 'importance option. - (erc-modified-channels-display): If erc-track-switch-direction is - 'importance, call erc-track-sort-by-importance. - (erc-track-face-priority): New function that returns a number - indicating the position of a face in erc-track-faces-priority-list. - (erc-track-sort-by-importance): New function that sorts - erc-modified-channels-list according to erc-track-face-priority. - (erc-track-get-active-buffer): Make 'oldest a rough opposite of - 'importance. - -2007-08-14 Jeremy Maitin-Shepard - - * erc-track.el (erc-track-remove-disconnected-buffers): New - variable which controls whether buffers associated with a server - that is disconnected should be removed from - `erc-modified-channels-alist'. Existing behavior is to - unconditionally remove such buffers, which is achieved by setting - `erc-track-removed-disconnected-buffers' to t. When set to t, - which is the new default value, such buffers remain in the list, - which I think is often the desired behavior, since the user may - likely wish to find out about activity that occurred in a channel - prior to it being disconnected. - (erc-track-list-changed-hook): New hook that is run whenever the - contents of `erc-modified-channels-alist' changes; it is useful - for users such as myself that don't use the default mode-line - notification but instead use a separate mechanism (which is tied - to my window manager) to provide notification of channel activity. - (erc-track-get-buffer-window): New function that acts as a wrapper - around `get-buffer-window' that handles the `selected-visible' - option of `erc-track-visibility'; previously, the value of - `erc-track-visibility' was passed directly to `get-buffer-window', - which does not support `selected-visible'; consequently, - `selected-visible' was not properly supported. - (erc-track-modified-channels): Fix a bug in the logic for removing - buffers from the list in certain cases. - (erc-track-position-in-mode-line): Add a supported value that - specifies that the tracking information should not be added to the - mode line at all. The value of nil is used to indicate that the - information should not be added at all to the mode line. - (erc-track-add-to-mode-line): Check for position eq to t, rather - than non-nil. - (erc-buffer-visible): Use erc-track-get-buffer-window. - (erc-modified-channels-update): Take - erc-track-remove-disconnected-buffers into account. - (erc-modified-channels-display): Run `erc-track-list-changed-hook'. - - * erc.el (erc-reuse-frames): New option that determines whether - new frames are always created. Defaults to t. This only has an - effect when erc-join-buffer is set to 'frame. - (erc-setup-buffer): Use it. - -2007-08-14 Michael Olson - - * erc-backend.el (erc-server-reconnect): If the server buffer has - been killed, use the current buffer instead. If the current - buffer is not an ERC buffer, give an error. This fixes a bug when - /reconnect is run from a channel buffer whose server buffer has - been deleted. Thanks to jbms for the report. - (erc-process-sentinel-1): Take server buffer as an argument, so - that we can make sure that it is current. - (erc-process-sentinel): Pass buffer to erc-process-sentinel-1. - (erc-process-sentinel-2): New function split from - erc-process-sentinel-1. If server buffer is deleted during a - reconnect attempt, stop trying to reconnect. Fix bug where - reconnect was not happening when erc-server-reconnect-attempts was - t. Call erc-server-reconnect-p only once each time. If we are - instructed to try connecting indefinitely, tell the user that they - can stop this by killing the server buffer. Call the process - sentinel by means of run-at-time, so that there is time to kill - the buffer if need be; this also removes the need for a while - loop. Refuse to reconnect again if erc-server-reconnect-timeout - is not an number. - - * erc.el (erc-command-no-process-p): Fix bug: the return value of - erc-extract-command-from-line is a list rather than a single - symbol. Thanks to jbms for the report. - (erc-cmd-RECONNECT): Use simpler logic, and use buffer-live-p - rather than bufferp. - (erc-send-current-line, erc-display-command, erc-display-msg): - Handle case where erc-server-process is nil, so that /reconnect - works. - -2007-08-12 Michael Olson - - * erc-identd.el (erc-identd-filter): Instead of sending an EOF - character, which now confuses freenode, stop the server process, - so that no new connections are accepted, and kill the current - client process. - -2007-07-29 Michael Olson - - * erc-list.el: Relicense to GPLv3. Since the file was already - licensed under version 2 or later, it turns out that we do not - need the permission of all of the authors in order to proceed. - -2007-07-13 Michael Olson - - * erc-goodies.el (erc-get-bg-color-face, erc-get-fg-color-face): - Use erc-error rather than message and beep. - - * erc-sound.el: Indentation fix. - - * erc.el (erc-command-no-process-p): New function that determines - if its argument is an ERC command that can be run when the server - process is not alive. - (erc-cmd-SET, erc-cmd-CLEAR, erc-cmd-COUNTRY, erc-cmd-HELP) - (erc-cmd-LASTLOG, erc-cmd-QUIT, erc-cmd-GQUIT) - (erc-cmd-RECONNECT, erc-cmd-SERVER): Denote that these commands - can be run even when the server process is not alive. - (erc-send-current-line): Call erc-command-no-process-p if the - server process is not alive, to determine if we have a command - that can be run anyway. Thanks to Tom Tromey for the bug report. - (erc-error): New function that either displays a message or throws - an error, depending on whether debug-on-error is non-nil. - (erc-cmd-SERVER, erc-send-current-line): Use it. - -2007-07-10 Michael Olson - - * Relicense all FSF-assigned code to GPLv3. - -2007-06-25 Michael Olson - - * erc.texi (Options): Fix typo. - (Getting Help and Reporting Bugs): Update webpage URL. Make Gmane - part more readable. - -2007-06-20 Michael Olson - - * erc-stamp.el (erc-timestamp-format-left): New option that - specifies the left timestamp to use for - erc-insert-timestamp-left-and-right. - (erc-timestamp-format-right): New option that specifies the right - timestamp to use for erc-insert-timestamp-left-and-right. - (erc-insert-timestamp-function): Change default to - erc-insert-timestamp-left-and-right. - (erc-insert-away-timestamp-function): Ditto. - (erc-timestamp-last-inserted-left) - (erc-timestamp-last-inserted-right): New variables to keep track - of data for erc-insert-timestamp-left-and-right. - (erc-insert-timestamp-left-and-right): New function that places - timestamps on both the left and right sides of the screen, but - only if each timestamp has changed since it was last computed. - Thanks to offby1 for urging me to merge this. - - * erc.el (erc-open-ssl-stream): Display informative error when - ssl.el not found. - (erc-tls): New function to connect using tls.el. - (erc-open-tls-stream): New function to initiate tls connection. - Display informative error when tls.el not found. - -2007-06-19 Michael Olson - - * erc-log.el: Update header with accurate instructions. - -2007-06-17 Michael Olson - - * erc-pkg.el: Update description to match what is currently in ELPA. - -2007-06-14 Juanma Barranquero - - * erc-goodies.el (erc-scroll-to-bottom): Remove redundant check. - -2007-06-13 Michael Olson - - * erc-compat.el (erc-with-selected-window): New compatibility - macro that implements `with-selected-window'. - - * erc-goodies.el (erc-scroll-to-bottom): Use it. This fixes a bug - with buffer ordering where ERC buffers would move to the top. - Thanks to Ivan Kanis for the patch. - -2007-06-10 Michael Olson - - * erc-log.el (erc-logging-enabled): Fix a bug that occurred when - `erc-log-channels-directory' had the name of a function. - -2007-06-06 Juanma Barranquero - - * erc.el (erc-show-channel-key-p, erc-startup-file-list): - Fix typo in docstring. - -2007-06-03 Michael Olson - - * erc-compat.el (erc-view-mode-enter): Make this its own function, - in order to document what we do, and provide sane fallback - behavior. - - * erc.el (erc-toggle-debug-irc-protocol): Don't pass any arguments - to erc-view-mode-enter, since we don't do anything special with - the exit function. This fixes a bug with Emacs 21 and Emacs 22. - Thanks to Leo for noticing. - -2007-05-30 Michael Olson - - * erc-compat.el (erc-user-emacs-directory): New variable that - determines where to find user-specific Emacs settings. For Emacs, - this is usually ~/.emacs.d, and for XEmacs this is usually - ~/.xemacs. - - * erc.el (erc-startup-file-list): Use erc-user-emacs-directory. - -2007-05-28 Michael Olson - - * erc-button.el (erc-button-url-regexp): Recognize parentheses as - part of URLs. Thanks to Lawrence Mitchell for the fix. - -2007-05-26 Michael Olson - - * erc.texi (Modules): Fix references to completion modules. - -2007-05-21 Michael Olson - - * Makefile (SOURCE): Remove erc-pkg.el. - (debclean): New rule to clean old Debian packages of ERC. - (debprepare): Don't modify the released tarball, but copy it as - the .orig.tar.gz file. - (debrelease, debrevision): Remove. - (debinstall): New target that copies the generated Debian file to - a distro-specific location. - (deb): New rule that chains together the stages in building a - Debian package. - (EXTRAS): Add erc-nicklist.el, since it is not release-quality. - (extras): Copy images directory. - - * erc-nicklist.el (erc-nicklist-icons-directory): Use - locate-library to find the "images" directory. This should be - more failsafe. Thanks to Tom Tromey for the idea. - -2007-05-19 Michael Olson - - * Makefile (ELPA): New variable that contains the location of my - local ELPA repository. - (elpa): New rule that makes an ELPA package for ERC. - -2007-04-19 Michael Olson - - * erc.el (erc-parse-prefix): New function that retrieves the - PREFIX server parameter from the current server and returns an - alist of prefix type to prefix character. - (erc-channel-receive-names): Use `erc-parse-prefix' to determine - whether the first character of a nick is a prefix character or - not. This should fix a bug reported by bromine about needing to - type "%" first to complete nicks of people who are "hops" on - Slashnet. This should also support for very exotic IRC server - setups, if any exist. - (erc-update-current-channel-member): Indentation. - -2007-04-15 Michael Olson - - * erc-log.el (erc-generate-log-file-name-function): Docfix. - Mention how to deal with the case for putting log files in - different directories. Change a customization type from `symbol' - to `function'. - (erc-log-channels-directory): Allow this to contain a function - name, which is called with the same args as in - `erc-generate-log-file-name-function'. Thanks to andrewy for the - report and use case. - (erc-current-logfile): Detect if `erc-log-channels-directory' is a - function and call it with arguments if so. - -2007-04-12 Michael Olson - - * erc-backend.el (define-erc-response-handler): Mention that hook - processing stops when the function returns non-nil. This should - help avoid a nasty "gotcha" when making custom functions. Thanks - to John Sullivan for the report. - -2007-04-08 Diane Murray - - * erc-nicklist.el (erc-nicklist-voiced-position): Fixed - customization mismatch. - -2007-04-01 Michael Olson - - * erc.el (erc-version-string): Release ERC 5.2. - - * erc-auto.in, erc-chess.el, erc-list.el, erc-speak.el: - * erc-viper.el: Update copyright notices. - - * erc.texi: Make Emacs Lisp source code in this document - essentially public domain. Update version to 5.2. - (Obtaining ERC): Mention extras tarball. - (Releases): Mention local GNU mirror. - (Sample Configuration): Remove notice. - - * FOR-RELEASE (5.3): Add item for erc-nicklist. - Mark NEWS as done. Mark extras tarball as done. - - * Makefile (VERSION): Increment to 5.2. - (TESTING): Remove. - (EXTRAS): New variable containing the contents of our "Emacs 22 - extras" tarball. - (SOURCE): Remove $(TESTING). - (MISC): Add COPYING and ChangeLog.06. Fix ChangeLog.NNNN -> - ChangeLog.NN. - (release): Use $(SNAPDIR) instead of erc-$(VERSION). - (extras): New rule which implements the building of the extras - tarball. - (upload-extras): New rule to upload the extras tarball. It's - yucky to replicate upload, but oh well. - (DISTRIBUTOR): New variable used to differentiate between building - packages for Ubuntu and Debian. - (debrelease, debrevision): Use it. - (debbuild): Run linda in addition to lintian. - - * NEWS: Mention extras tarball. Note which files have been - renamed. Note that erc-list is enabled by default, except in - Emacs 22. - - * README.extras: New file which serves as a README for the extras - tarball. - -2007-03-31 Michael Olson - - * NEWS: Update for the 5.2 release. - - * FOR-RELEASE: Finish up 5.2 manual item. Add documentation item - for 5.3. - - * erc.texi (Sample Session): Flesh out. Mention #erc. - (Modules): Defer to 5.3 release. - (Advanced Usage): Move Sample Configuration chapter ahead of - unfinished chapters. - (Sample Configuration): Write. - (Options): Mention how to see available ERC options. Defer to 5.3 - release. - (Tips and Tricks): Remove, since it seems better to just include - tips and tricks in the sample configuration, commented out. - - * erc-bbdb.el (erc-bbdb-search-name-and-create): Make prompt more - informative about how to skip merging. - (erc-bbdb-insinuate-and-show-entry-1): Move contents of - erc-bbdb-insinuate-and-show-entry here. - (erc-bbdb-insinuate-and-show-entry): Run - erc-bbdb-insinuate-and-show-entry-1 "outside" of the calling - function, so that we can avoid triggering a process-filter error - if the user hits C-g. - -2007-03-30 Michael Olson - - * FOR-RELEASE: Solve C-c C-SPC keybinding dilemma. - - * erc-autoaway.el (erc-autoaway-idle-method): Use `if' rather than - `cond' and `set' rather than `set-default'. - - * erc-log.el: Avoid compiler warning by requiring erc-network - during compilation. - (erc-generate-log-file-name-function): Add tag to each option. - Add erc-generate-log-file-name-network. - (erc-generate-log-file-name-network): New function which generates - a log file name that uses network name rather than server name, - when possible. - - * erc-track.el (track): Assimilate track-when-inactive module, - since there's no need to have two modules in one file -- an option - will do. Remove track-modified-channels alias. Call - erc-track-minor-mode-maybe, and tear down the minor mode when - disabling. - (erc-track-when-inactive): New option which determines whether to - track visible buffers when inactive. The default is not to do so. - (erc-track-visibility): Mention erc-track-when-inactive. - (erc-buffer-visible): Use erc-track-when-inactive. - (erc-track-enable-keybindings): New option which determines - whether to enable the global-level tracking keybindings. The - default is to do so, unless they would override another binding, - in which case we prompt the user about it. - (erc-track-minor-mode-map): Move global keybindings here. - (erc-track-minor-mode): New minor mode which only enables the - keybindings and does nothing else. - (erc-track-minor-mode-maybe): New function which starts - erc-track-minor-mode, but only if it hasn't already been started, - an ERC buffer exists, and the user OK's it, depending on the value - of `erc-track-enable-keybindings'. - (erc-track-switch-buffer): Display a message if someone calls this - without first enabling erc-track-mode. - -2007-03-17 Michael Olson - - * erc.texi (Development): Mention ErcDevelopment page on - emacswiki. - (Getting Started): Mention ~/.emacs.d/.ercrc.el and the Customize - interface. - (Sample Session): New section that has a very rough draft for a - sample ERC session. - (Special Features): New section that explains some of the special - features of ERC. Taken from ErcFeatures on emacswiki, with - enhancements. - -2007-03-12 Diane Murray - - * erc-autoaway.el (erc-autoaway-idle-method): When setting the new - value, disable and re-enable `erc-autoaway-mode' only if it was - already enabled. This fixes a bug where autoaway was enabled just - by loading the file. - -2007-03-10 Diane Murray - - * erc-capab.el: Added more information to the Usage section. - (erc-capab-identify-prefix): Doc fix. - (erc-capab-identify-unidentified): New face. - (290): Removed. Definition moved to erc-backend.el. - (erc-capab-identify-send-messages): Renamed from - `erc-capab-send-identify-messages'. - (erc-capab-identify-setup): Use it. - (erc-capab-identify-get-unidentified-nickname): Renamed from - `erc-capab-get-unidentified-nickname'. - (erc-capab-identify-add-prefix): Use it. Use - `erc-capab-identify-unidentified' as the face. - - * erc-backend.el (290): Moved here from erc-capab.el. - - * erc.el (erc-select): Added an autoload cookie. - (erc-message-type-member, erc-restore-text-properties): Use - `erc-get-parsed-vector'. - (erc-auto-query): Set the default to 'bury since many new users - expect private messages from others to be in dedicated query - buffers, not the server buffer. - (erc-common-server-suffixes): Use "freenode" for freenode.net, not - "OPN". Added oftc.net. - - * NEWS: Added note about erc-auto-query's new default setting. - -2007-03-03 Michael Olson - - * erc.el (erc-open, erc): Docfixes. - -2007-03-02 Michael Olson - - * FOR-RELEASE: Make section for 5.3 release and move erc-backend - cleanup there. Awaiting discussion before doing other things. - Add tasks for merging filename changes from the 5.2 release - branch, and for making a tarball of modules not in Emacs 22. Add - item to remind me to update NEWS. Mark backtab entry as done. - - * erc-button.el (button): Add call to `erc-button-add-keys'. - (erc-button-keys-added): New variable tracking whether we've added - the keys yet. - (erc-button-add-keys): New function that adds the key to - erc-mode-map. - - * erc.texi: Change version to 5.2 (pre-release). - -2007-02-15 Michael Olson - - * CREDITS: Update. - - * erc-backend.el (erc-server-send-ping-interval): Change to use a - default of 30 seconds. Improve customize interface. - (erc-server-send-ping-timeout): New option that determines when to - consider a connection stalled and restart it. The default is - after 120 seconds. - (erc-server-send-ping): Use erc-server-send-ping-timeout instead - of erc-server-send-ping-interval. If - erc-server-send-ping-timeout is nil, do not ever kill and restart - a hung IRC process. - - * erc.el (erc-modules): Include the name of the module in its - description. This should make it easier for people to find and - enable a particular module. - -2007-02-15 Vivek Dasmohapatra - - * erc.el (erc-cmd-RECONNECT): Kill old process if it is still - alive. - (erc-message-english-PART): Properly escape "%" characters in - reason. - - * erc-backend.el (erc-server-reconnecting): New variable that is - set when the user requests a reconnect, but the old process is - still alive. This forces the reconnect to work even though the - process is killed manually during reconnect. - (erc-server-connect): Initialize it. - (erc-server-reconnect-p): Use it. - (erc-process-sentinel-1): Set it to nil after the first reconnect - attempt. - -2007-02-07 Diane Murray - - * erc-menu.el (erc-menu-definition): Fixed so that the separator - is between "Current channel" and "Pals, fools and other keywords", - not at the bottom of the "Current channel" submenu. - -2007-01-25 Diane Murray - - * erc-networks.el (erc-server-alist): Removed SSL server for now - since `erc-server-select' doesn't know to use `erc-ssl'. - - * erc-networks.el (erc-server-alist, erc-networks-alist): Added - definitions for oftc.net. - - * erc-services.el (erc-nickserv-alist): Fixed OFTC message regexp. - -2007-01-22 Michael Olson - - * erc-backend.el (erc-server-error-occurred): New variable that - indicates when an error has been signaled by the server. This - should fix an infinite reconnect bug when giving some servers a - bogus :full-name. Thanks to Angelina Carlton for the report. - (erc-server-connect): Initialize erc-server-error-occurred. - (erc-server-reconnect-p): Use it. - (ERROR): Set it. - - * erc-services.el (erc-nickserv-alist): Alphabetize and add Ars - and QuakeNet. Standardize look of entries. Fix type mismatch - error in customize interface. - (erc-nickserv-passwords): Alphabetize and add missing entries from - erc-nickserv-alist. - -2007-01-21 Michael Olson - - * erc.el (erc-header-line-format): Document how to disable the - header line, and add a customization type for it. Also, make the - changes take effect immediately. - -2007-01-19 Michael Olson - - * erc.texi (Modules): Document new menu module. Thanks to Leo - for noticing. - -2007-01-16 Diane Murray - - * erc-stamp.el (erc-insert-timestamp-left): Fixed so that the - whitespace string filler is hidden correctly when timestamps are - hidden. - (erc-toggle-timestamps): New function to use instead of - `erc-show-timestamps' and `erc-hide-timestamps'. - - * erc.el (erc-restore-text-properties): Moved here from - erc-fill.el since it could be useful in general. - - * erc-fill.el (erc-restore-text-properties): Removed. - -2007-01-13 Michael Olson - - * erc.el (erc-command-regexp): New variable that is used to match - a command. - (erc-send-input): Use it. This fixes a bug where paths -- - "/usr/bin/foo", for example -- were being displayed as commands, - but still sent correctly. - (erc-extract-command-from-line): Use it. - - * erc.texi (Modules): Document erc-capab-identify. - -2007-01-11 Diane Murray - - * erc.el (erc-find-parsed-property): Moved here from erc-track.el - since it can be useful in general. - - * erc-track.el (erc-find-parsed-property): Removed. - - * erc-capab.el (erc-capab-find-parsed): Removed. - (erc-capab-identify-add-prefix): Use `erc-find-parsed-property'. - - * erc.el (erc-open): Run `erc-before-connect' hook here. This - makes sure the hook always gets called before a connection is - made, as some functions, like `erc-handle-irc-url', use `erc-open' - instead of `erc'. - (erc): Removed `erc-before-connect' hook. - - * erc-menu.el (erc-menu-definition): Put items specific to - channels in a "Current channel" submenu. - - * erc-backend.el (321, 323): Display channel list in server buffer - when not using the channel list module. - - * erc.el: Updated copyright years. - (erc-version-string): Set to 5.2 (devel). - (erc-format-lag-time): Fixed to work when `erc-server-lag' is nil. - (erc-update-mode-line-buffer): Set the header face. - -2007-01-11 Michael Olson - - * erc-bbdb.el (erc-bbdb-popup-type): Fix customization type and - documentation. - - * erc-services.el (erc-nickserv-identify-mode): Improve - documentation for nick-change option and move higher to fix - compiler warning. Avoid a recursive load error. - (erc-nickserv-alist): Add simple entry for BitlBee, to avoid - "NickServ is AWAY: User is offline" error. Oddly enough, bitlbee - was smart enough to recognize that as an authentication request - and log in regardless, which is why I didn't notice this earlier. - (erc-nickserv-alist-sender, erc-nickserv-alist-regexp) - (erc-nickserv-alist-nickserv, erc-nickserv-alist-ident-keyword) - (erc-nickserv-alist-use-nick-p) - (erc-nickserv-alist-ident-command): New accessors for - erc-nickserv-alist. Using nth is unwieldy. - (erc-nickserv-identify-autodetect) - (erc-nickserv-identify-on-connect) - (erc-nickserv-identify-on-nick-change, erc-nickserv-identify): Use - the new accessors. - -2007-01-11 Diane Murray - - * NEWS: Added note for `erc-my-nick-face'. Fixed capab-identify - wording. - -2007-01-10 Diane Murray - - * erc.el (erc-mode-line-format): Added %l to documentation. - (erc-header-line-format): Removed "[IRC]". Use the new %l - replacement character. Doc fix. - (erc-format-channel-modes): Removed lag code. Removed parentheses - from mode string. - (erc-format-lag-time): New function. - (erc-update-mode-line-buffer): Use it. - -2007-01-10 Michael Olson - - * erc.el: Fix typo in url-irc-function instructions. - -2007-01-09 Michael Olson - - * erc.el (erc-system-name): New option that determines the system - name to use when logging in. The default is to figure this out by - calling `system-name'. - (erc-login): Use it. - -2007-01-07 Michael Olson - - * erc.el (erc-modules): Add the menu module. This should fix a - bug with incorrect ERC submenus being displayed. - - * erc-menu.el: Turn this into a module. - (erc-menu-add, erc-menu-remove): New functions that add and remove - the ERC menu. - -2006-12-28 Michael Olson - - * erc-list.el: Change header to mention that this is part of ERC, - rather than GNU Emacs. - - * erc-networks.el (erc-server-alist): Add Ars OpenIRC and - LinuxChix networks. Thanks to Angelina Carlton for mentioning - them. Properly escape periods in Konfido.Net and Kewl.Org. - (erc-networks-alist): Add entries for Ars and LinuxChix, though - the latter does not actually provide an announced network name. - - * erc-services.el (erc-nickserv-identify-mode): Add 'both method, - which waits for a NickServ message if the network supports it, - otherwise sends the password after connecting. - (erc-nickserv-identify-mode): Default to 'both. - (erc-nickserv-passwords): Add OFTC and Azzurra to custom options. - (erc-nickserv-alist): Indentation fix. - (erc-nickserv-identify-on-connect) - (erc-nickserv-identify-on-nick-change): Handle 'both method. - -2006-12-28 Leo Liu (tiny change) - - * erc.el (erc-iswitchb): Wrap body in unwind-protect so that - hitting C-g does not leave iswitchb-mode on. - -2006-12-27 Michael Olson - - * erc.el (erc-cmd-RECONNECT): New command that calls - erc-server-reconnect. - - * erc-backend.el (erc-server-reconnect-count): New server variable - that keeps track of reconnection attempts. - (erc-server-reconnect-attempts): New option that determines the - number of reconnection attempts that ERC will make per server. - (erc-server-reconnect-timeout): New option that determines the - amount of time, in seconds, that ERC will wait between successive - reconnect attempts. - (erc-server-reconnect): New function that reestablishes the - current IRC connection. Move some commands from - erc-process-sentinel-1 here. - (erc-process-sentinel-1): If we have been disconnected, loop until - we either reconnect or run out of attempts. - (erc-server-reconnect-p): Move higher and make this a defsubst, - since I'm worried about the current buffer changing from - underneath us. Implement limit of number of reconnect attempts.. - - * erc.texi (Getting Started): Update for /RECONNECT command. - -2006-12-26 Michael Olson - - * erc.el (erc-open): Restore old point correctly, or at least get - closer to doing so than before. - -2006-12-13 Leo Liu (tiny change) - - * erc.el (erc-iswitchb): Temporarily enable iswitchb mode if it - isn't active already, instead of leaving it on. - -2006-12-10 Juanma Barranquero - - * erc-ezbounce.el (erc-ezb-init-session-list): Doc fix. - -2006-12-08 Michael Olson - - * erc.el: Re-evaluate contributions from a contributor, and found - them under 15 lines of non-obvious code, so it is safe to remove - the copyright notice. - (erc-modules): Remove list module. - - * erc-list.el: Remove, since a contributor who has not completed - their assignment has contributed significantly more than 15 lines - of code to this file. - -2006-11-28 Juanma Barranquero - - * erc.el (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Simplify. - (erc-prompt-for-channel-key, erc-ignore-reply-list, erc-send-post-hook) - (erc-active-buffer, erc-join-buffer, erc-frame-alist, erc-with-buffer) - (erc-modules, erc-display-message-highlight, erc-process-input-line) - (erc-cmd-HELP, erc-server-hooks, erc-echo-notice-in-user-buffers) - (erc-format-my-nick, erc-echo-notice-in-user-and-target-buffers) - (erc-echo-notice-in-first-user-buffer, erc-connection-established) - (erc-update-user-nick, erc-update-channel-member, erc-highlight-notice) - (erc-command-symbol, erc-add-query, erc-process-script-line) - (erc-determine-parameters, erc-client-info, erc-popup-input-buffer): - (erc-script-echo): Fix typos in docstrings. - (erc-channel-user-op-p, erc-channel-user-voice-p, erc-startup-file-list) - (define-erc-module, erc-once-with-server-event) - (erc-once-with-server-event-global, erc-debug-irc-protocol) - (erc-log-irc-protocol, erc-cmd-LOAD, erc-update-user) - (erc-update-current-channel-member, erc-load-script): - (erc-mode-line-away-status-format): Doc fixes. - -2006-11-20 Andrea Russo (tiny change) - - * erc-dcc.el (erc-dcc-chat-setup): Initialize `erc-input-marker' - before calling `erc-display-prompt'. - -2006-11-24 Juanma Barranquero - - * erc.el (erc-after-connect, erc-open-ssl-stream) - (erc-display-line-1, erc-display-line): - * erc-backend.el (005): Fix space/tab mixup in docstrings. - -2006-11-20 Michael Olson - - * erc.el (erc-version-string): Call this Version 5.2 stable - pre-release, since it diverges slightly from our 5.2 branch, in - that unstable features are not included. - (erc-update-modules): Display better error message when module not - found. - -2006-11-12 Michael Olson - - * erc-log.el: Save all log buffers when Emacs exits, in case - someone ignores the warning about open processes. Remove the - advice code in the commentary. - (erc-save-query-buffers): Docfix. - (erc-log-save-all-buffers): New function that saves all ERC - buffers to logs. - (erc-current-logfile): Fix bug in filename selection, where the - current buffer was erroneously being preferred over the given - buffer. - -2006-11-08 Michael Olson - - * erc.el (erc-string-to-port): Avoid error when a numerical port - is passed. Thanks to Zekeriya KOÇ for the report. - -2006-11-08 Łukasz Demianiuk (tiny change) - - * erc.el (erc-header-line): Fix typo. - -2006-11-06 Juanma Barranquero - - * erc-dcc.el (erc-dcc-send-file): Fix typo in error message. - - * erc.el (read-passwd): - * erc-autoaway.el (erc-autoaway-reestablish-idletimer): - * erc-truncate.el (truncate): Fix typo in docstring. - -2006-10-21 Michael Olson - - * erc.el (erc-iswitchb): Fix bug when hitting C-c C-b without - first loading iswitchb. Thanks to Leo for the report. - -2006-10-10 Michael Olson - - * erc.el (erc-default-port): Make the default be 6667 instead of - ircd. since Mac OS X apparently has problems with looking up that - port name. - - * erc-backend.el (353): Receive names after displaying the initial - message, instead of before. - -2006-10-05 Diane Murray - - * erc.el (erc-my-nick-face): New face. - (erc): Use FULL-NAME argument, not `erc-user-full-name'. This - fixes a bug where the :full-name argument passed to the function - was not respected. - (erc-format-my-nick): Use `erc-my-nick-face'. This should help - make it easier to find messages you sent in conversations when - `erc-show-my-nick' is non-nil. - (erc-compute-server): Doc fix. - -2006-10-01 John J Foerch (tiny change) - - * erc-stamp.el (erc-insert-timestamp-right): Exclude the newline - from the erc-timestamp field. - -2006-09-11 Michael Olson - - * erc-nicklist.el (erc-nicklist-insert-contents): Add missing - parenthesis. Thanks to Stephan Stahl for the report. - -2006-09-10 Eric Hanchrow - - * erc.el (erc-cmd-IGNORE): Prompt user if this might be a regexp - instead of a single user. - -2006-09-10 Michael Olson - - * erc.el (erc-generate-new-buffer-name): If this is a server - buffer and a process exists already, create a new buffer. - (erc-open): If the IRC session was continued, restore the old - point. Thanks to Stephan Stahl for the report. - (erc-member-ignore-case): Coding style tweak. - (erc-cmd-UNIGNORE): Quote the user before comparison. If we don't - find the user listed verbatim, try to match them against the list - using string-match. In this case, prompt as to whether the regexp - should be removed. - (erc-ignored-user-p): Remove CL-ism. - - * erc-autoaway.el (erc-autoaway-possibly-set-away): Check to see - whether we are already away. - - * erc-menu.el: Fix potential compiler warning. - -2006-09-07 Diane Murray - - * erc.el: Updated Commentary and URL. - (erc-iswitchb, erc-display-line, erc-set-modes, erc-update-modes) - (erc-arrange-session-in-multiple-windows): No need to check if - `erc-server-process' is bound. - (erc-server-buffer-live-p): Doc fix. - (erc-part-from-channel): Don't use any initial contents at prompt. - (erc-format-nick, erc-format-@nick): Doc fix. Use `when'. - (s367): Fixed to support only banmask and channel which is the - standard. Also, there's no reason to add a message to each banned - user entry trying to persuade the user to use /banlist instead of - /mode #channel +b. That part of the message was a little - confusing, anyways. - (s367-set-by): New catalog entry. The user who set the ban and - the time of ban seem to be specific to only certain servers such - as freenode. - - * erc-autoaway.el (erc-autoaway-idletimer): Doc fix. - - * erc-backend.el (erc-server-process-alive): No need to check if - `erc-server-process' is bound. - (367): Use s367 or s367-set-by where appropriate. - - * erc-compat.el: Fixed URL. - - * erc-dcc.el: Updated copyright years. Added Usage section. - Changed supported Emacs version number from 21.3.50 to 22 in - Commentary. - - * erc-ibuffer.el (erc-server-name, erc-target, erc-away): No need - to check if `erc-server-process' is bound. - - * erc-nicklist.el: Added to the Commentary section an explanation - that `erc-nicklist-quit' should be called from within the nicklist - buffer. Set file coding to utf-8 so a contributor's name is - displayed correctly. - (erc-nicklist-icons-directory): Use customize type directory - instead of string. - (erc-nicklist-insert-contents): Set bbdb-nick to an empty string - if it wasn't found. This fixes a bug where an error would occur - when using `string=' on bbdb-nick if it was nil. - - * erc-replace.el: Removed URL from file information since it - doesn't exist. - - * erc-sound.el: Updated copyright years. Fixed Commentary and - added Usage section. - (define-erc-module): Add and remove `erc-ctcp-query-SOUND' to - `erc-ctcp-query-SOUND-hook' here. Removed the keybinding - definitions. - (erc-play-sound, erc-default-sound, erc-cmd-SOUND) - (erc-ctcp-query-SOUND): Doc fix. - (erc-play-command): Removed, not necessary anymore. - (erc-ctcp-query-SOUND-hook): Set to nil as default. Moved up - higher in code, added docstring. - (erc-play-sound): Use `play-sound-file'. It exists in GNU Emacs - as well since version 21 or earlier. Removed commented-out older - version of function. - - * NEWS: Fixed formatting, added channel tracking change. - -2006-09-03 Diane Murray - - * erc.el: M-x erc RET can now be used to start ERC. - (erc-open): Renamed from `erc'. - (erc-before-connect): Change erc-select to erc. - (erc): Renamed from `erc-select'. Use `erc-open'. - (erc-select): Defined as alias of `erc'. - (erc-ssl): Renamed from `erc-select-ssl'. Use `erc'. - (erc-select-ssl): Defined as alias of `erc-ssl'. - (erc-cmd-SERVER): Use `erc'. - (erc-query, erc-handle-irc-url): Use `erc-open'. - - * erc-backend.el (erc-process-sentinel-1, JOIN): Use `erc-open'. - - * erc-menu.el (erc-menu-definition): Use `erc'. - - * erc-networks.el: Updated copyright years. - (erc-server-select): Use keyword arguments when calling `erc'. - - * erc.texi (Getting Started, Connecting): Changed erc-select to - erc. - - * README: Changed erc-select to erc. - - * NEWS: Added note about these changes. - - * FOR-RELEASE: Marked this item as done. - -2006-08-21 Diane Murray - - * erc-track.el (erc-track-mode-line-mouse-face): New variable. - (erc-make-mode-line-buffer-name): Add help-echo and mouse-face - properties to channel name. - -2006-08-20 Michael Olson - - * erc-identd.el (erc-identd): New customization group. - (erc-identd-port): New option that specifies the port to use if - none is given as an argument to erc-identd-start. - (identd): Place erc-identd-quickstart in erc-connect-pre-hook - instead of erc-identd-start so that we deal with the different - meaning of the first argument. - (erc-identd-start): Use erc-identd-port. - (erc-identd-quickstart): New function that ignores any arguments - and calls erc-identd-start. - - * erc.el (erc-with-server-buffer): New macro that switches to the - current ERC server buffer and runs some code. If no server buffer - is available, return nil. This is a useful way to access - variables in the server buffer. - (erc-get-server-user, erc-add-server-user) - (erc-remove-server-user, erc-change-user-nickname) - (erc-get-server-nickname-list, erc-get-server-nickname-alist) - (erc-ison-p, erc-active-buffer, erc-cmd-IGNORE) - (erc-cmd-UNIGNORE, erc-cmd-IDLE, erc-cmd-NICK, erc-cmd-BANLIST) - (erc-cmd-MASSUNBAN, erc-nickname-in-use, erc-ignored-user-p) - (erc-format-channel-modes): Use it. - (erc-once-with-server-event, erc-once-with-server-event-global) - (erc-with-buffer, erc-with-all-buffers-of-server): Use make-symbol - instead of gensym. - (erc-open-server-buffer-p): New function that returns non-nil if - the given buffer is an ERC server buffer that has an open IRC - process. - (erc-with-buffer): Use buffer-live-p here to set a good example, - though it isn't really needed here. - (erc-away): Mention erc-away-time. - (erc): Don't propagate the erc-away setting, since it makes more - sense to access it from the server buffer. Set up the prompt - before connecting rather than after. Run erc-connect-pre-hook - with the buffer as an argument, instead of no arguments. - (erc-cmd-GAWAY): Use erc-open-server-buffer-p instead of - erc-server-buffer-p so that only open connections are set away. - (erc-cmd-GQUIT): Use erc-open-server-buffer-p. - (erc-process-away): Docfix. Don't set erc-away in channel - buffers. - (erc-set-current-nick): Make this uniform with the style used in - erc-current-nick. - (erc-away-time): Rename from erc-away-p, since this is no longer a - boolean-style predicate. - (erc-format-away-status): Use it. - (erc-initialize-log-marker): Accept a `buffer' argument. - (erc-connect-pre-hook): Docfix. - (erc-connection-established): Make sure this runs in the correct - buffer. - (erc-set-initial-user-mode): Accept a `buffer' argument. - - * erc-stamp.el (erc-add-timestamp): Use erc-away-time. - - * erc-spelling.el (erc-spelling-init): Use - erc-with-server-buffer. Accept `buffer' argument. - (spelling): Call erc-spelling-init with the `buffer' argument. - - * erc-speedbar.el (erc-speedbar-buttons): Use erc-server-buffer-p. - - * erc-pcomplete.el (pcomplete/erc-mode/UNIGNORE) - (pcomplete-erc-all-nicks): Use erc-with-server-buffer. - - * erc-notify.el (erc-notify-timer, erc-cmd-NOTIFY): Use - erc-with-server-buffer. - - * erc-networks.el (erc-network, erc-current-network) - (erc-network-name): Use erc-with-server-buffer. - - * erc-netsplit.el (erc-cmd-WHOLEFT): Use erc-with-server-buffer. - - * erc-match.el (erc-log-matches, erc-log-matches-come-back): Use - erc-away-time. - - * erc-log.el (log): Use erc-away-time. Remove unnecessary check. - Pass `buffer' argument to erc-log-setup-logging instead of setting - the current buffer. Ditto for erc-log-disable-logging. - (erc-log-setup-logging, erc-log-disable-logging): Accept a `buffer' - argument. - - * erc-list.el (erc-chanlist): Use erc-with-server-buffer. - - * erc-ibuffer.el (erc-away): Use erc-away-time. - - * erc-dcc.el (erc-dcc-get-filter): Temporarily make the buffer - read only instead of permanently doing so. - - * erc-compat.el (erc-gensym, *erc-sym-counter*): Remove, since - Emacs Lisp has make-symbol, which is better. - - * erc-chess.el (erc-chess-handler, erc-cmd-CHESS): Use - erc-with-server-buffer. - - * erc-capab.el (capab-identify): Only deal with server buffers - that have an open IRC process. - (erc-capab-identify-add-prefix): Use erc-with-server-buffer. - - * erc-backend.el (erc-server-connected): Docfix. Recommend the - `erc-server-process-alive' function. - (erc-coding-system-for-target): Supply a default target if one is - not given. - (erc-server-send): Simplify slightly. - (erc-call-hooks): Use erc-with-server-buffer. - (erc-server-connect, erc-server-setup-periodical-ping): Accept - `buffer' argument. - - * erc-autoaway.el (erc-autoaway-reestablish-idletimer): Move - higher to avoid an automatic load snafu. - (erc-autoaway-some-server-buffer): New function that returns an - ERC server buffer with a live connection, or nil otherwise. - (erc-autoaway-insinuate-maybe): New function that adds the - autoaway reset function to post-command-hook if at least one ERC - process is alive. - (erc-autoaway-remove-maybe): New function that removes the - autoaway reset function from post-command-hook if no ERC process - is alive. - (autoaway): Don't touch post-command-hook unless an IRC process is - already open. Remove our addition to post-command-hook as soon as - there are no more IRC processes open. Reset the indicators before - connecting to an IRC server, which fixes a bug when re-connecting. - (erc-autoaway-reset-idle-user): Call erc-autoaway-remove-maybe if - there are no more IRC processes open. - (erc-autoaway-set-back): Pick an open IRC process. Accept an - argument which is a function call if we can't find one. - (erc-autoaway-some-open-server-buffer): New function which returns - an ERC server buffer with an open connection and a user that is - not away. - (erc-autoaway-possibly-set-away, erc-autoaway-set-away): Use it. - (erc-autoaway-set-away): Accept a `notest' argument which is used - to avoid testing the same thing twice. - (erc-autoaway-last-sent-time, erc-autoaway-caused-away): Move - higher in file to fix byte-compile warning. - -2006-08-20 Diane Murray - - * erc-backend.el (erc-process-sentinel-1): Doc fix. Let - `erc-server-reconnect-p' check all condition cases. - (erc-server-reconnect-p): Moved rest of checks from - `erc-process-sentinel-1' to here. Now takes an argument, EVENT. - -2006-08-14 Diane Murray - - * erc-menu.el: Updated copyright years. Removed EmacsWiki URL. - (erc-menu-definition): Name the menu "ERC" instead of "IRC" to - avoid confusion with rcirc and other clients. - - * erc-backend.el (erc-server-banned): New variable. - (erc-server-connect): Set `erc-server-banned' to nil. - (erc-process-sentinel-1): Use `erc-server-reconnect-p'. - (erc-server-reconnect-p): New function. Return non-nil if the - user wants automatic reconnects and if the user has not been - banned from the server. This should fix a bug where ERC gets into - a loop trying to reconnect with no way to stop it when the user is - denied access to the server due to a server ban. It might also - help when Tor users are blocked from freenode if freenode servers - send the 465 message before disconnecting. - (465): Handle "banned from server" error notices. - -2006-08-13 Romain Francoise - - * erc-match.el (erc-log-matches-make-buffer): End `y-or-n-p' - prompt with a space. - -2006-08-13 Michael Olson - - * erc-backend.el (erc-server-timed-out): New variable that - indicates whether the current connection has timed out due to - failure to respond to a ping. - (erc-server-send-ping): Set erc-server-timed-out to t. - (erc-server-connect): Initialize erc-server-timed-out to nil. - (erc-process-sentinel-1): Consult erc-server-timed-out. - -2006-08-11 Michael Olson - - * erc-fill.el (erc-fill): Skip any initial empty lines so that we - avoid errors when inserting disconnect messages and other messages - that begin with newlines. - -2006-08-07 Michael Olson - - * erc-backend.el (erc-process-sentinel-1): Use erc-display-message - in several places instead of inserting text. - (erc-process-sentinel): Move to the input-marker before removing - the prompt. - - * erc.el (erc-port): Fix customization options. - (erc-display-message): Handle null type explicitly. Previously, - this was relying on a chance side-effect. Cosmetic indentation - tweak. - (english): Add 'finished and 'terminated entries to the catalog. - Add initial and terminal newlines to 'disconnected and - 'disconnected-noreconnect entries. Avoid long lines. - (erc-cmd-QUIT): Bind the current erc-server-process to - server-proc. If the IRC server responds quickly, it is possible - for the connection to close, and hence server buffer to be killed, - if erc-kill-server-buffer-on-quit is non-nil. This avoids that - problem. - -2006-08-06 Michael Olson - - * erc-backend.el (erc-server-send-queue): Update from Circe - version of this function. - (erc-server-ping-timer-alist): New variable that keeps track of - ping timers according to their associated server. - (erc-server-last-received-time): New variable that specifies the - time of the last message we received from the server. This is - used to detect hung processes. - (erc-server-send-ping): New function that sends a ping to the IRC - process corresponding with the given buffer. Split from - erc-server-setup-periodical-ping. If the server buffer no longer - exists, cancel the timer. If the server process has not given us - a message, including PING responses, since the last PING, kill it. - This is necessary to deal with some aberrant freenode behavior. - Idea taken from rcirc. - (erc-server-setup-periodical-ping): Rename from - erc-server-setup-periodical-server-ping. - (erc-server-filter-function): Use erc-current-time instead of - current-time. - - * erc.el (erc-arrange-session-in-multiple-windows): Fix bug with - multi-tty Emacs. - (erc-select-startup-file): Fix bug introduced by recent change. - (erc-cmd-QUIT): If the IRC process has not terminated itself - within 4 seconds of completing our quit-hook, kill it manually. - Freenode in particular needs this. - (erc-connection-established): Use erc-server-setup-periodical-ping - instead of erc-server-setup-periodical-server-ping. - -2006-08-05 Michael Olson - - * erc-log.el (erc-log-standardize-name): New function that returns - a filename that is safe for use for a log file. - (erc-current-logfile): Use it. - - * erc.el (erc-startup-file-list): Search in ~/.emacs.d first, - since that is a fairly standard directory. - (erc-select-startup-file): Re-write to use - convert-standard-filename, which will ensure that MS-DOS systems - look for the _ercrc.el file. - -2006-08-02 Michael Olson - - * erc.el (erc-version-string): Release ERC 5.1.4. - - * Makefile, NEWS, erc.texi: Update for the 5.1.4 release. - - * erc.el (erc-active-buffer): Fix bug that caused messages to go - to the wrong buffer. Thanks to offby1 for the report. - - * erc-backend.el (erc-coding-system-for-target): Handle case where - target is nil. Thanks to Kai Fan for the patch. - -2006-07-29 Michael Olson - - * erc-log.el (erc-log-setup-logging): Don't offer to save the - buffer. It will be saved automatically killed. Thanks to Johan - Bockgård and Tassilo Horn for pointing this out. - -2006-07-27 Johan Bockgård - - * erc.el (define-erc-module): Make find-function and find-variable - find the names constructed by `define-erc-module' in Emacs 22. - -2006-07-14 Michael Olson - - * erc-log.el (log): Make sure that we enable logging on - already-opened buffers as well, in case the user toggles this - module after loading ERC. Also be sure to remove logging ability - from all ERC buffers when the module is disabled. - (erc-log-setup-logging): Set buffer-file-name to nil rather than - the empty string. This should fix some errors that occur when - quitting Emacs without first killing all ERC buffers. - (erc-log-disable-logging): New function that removes the logging - ability from the current buffer. - - * erc-spelling.el (spelling): Use dolist and buffer-live-p. - -2006-07-12 Michael Olson - - * erc-match.el (erc-log-matches): Bind inhibit-read-only rather - than call toggle-read-only. - - * erc.el (erc-handle-irc-url): Move here from erc-goodies.el and - add autoload cookie. - -2006-07-09 Michael Olson - - * erc.el (erc-version-string): Release ERC 5.1.3. - - * erc.texi: Update for the 5.1.3 release. - - * erc-autoaway.el (erc-autoaway-set-back): Fix bug after returning - from being set automatically away and current buffer is not an ERC - buffer. - - * erc-identd.el: Fix compiler error. - - * erc.texi (Development): Use @subheading instead of @subsection. - (Advanced Usage): Add menu. - (Connecting): Fully document how to connect to an IRC server. - (Options, Tips and Tricks, Sample Configuration): New unwritten - sections. - - * erc.el (erc-server, erc-port, erc-nick, erc-nick-uniquifier) - (erc-user-full-name, erc-password): Docfixes and customization - interface tweaks. - (erc-try-new-nick-p): Rename from - `erc-manual-set-nick-on-bad-nick-p' and invert meaning. - (erc-nickname-in-use): Use `erc-try-new-nick-p'. Check the length - of `erc-nick-uniquifier', in case someone wants multiple - characters. - (erc-compute-server, erc-compute-nick, erc-compute-full-name) - (erc-compute-port): Docfixes. - - * erc-log.el (log): Move all add-hook calls here, rather than - executing them immediately, and also cause them to be un-hooked - when the module is removed. - (erc-save-buffer-on-part): Move next to - `erc-save-queries-on-quit'. - (erc-save-buffer-on-quit, erc-save-queries-on-quit): Default to t. - (erc-log-write-after-send, erc-log-write-after-insert): Default to - nil. This makes things fast, but reasonably failsafe, by default. - -2006-07-08 Michael Olson - - * erc-log.el (erc-log-insert-log-on-open): Make this nil by - default, since most IRC clients don't do this. - (erc-log-write-after-send): New option that determines whether the - log file will be written to after every sent message. - (erc-log-write-after-insert): New option that determines whether - the log file will be written to when new text is added to a logged - ERC buffer. - (log): Use the aforementioned options. - - * erc.texi (Modules): Document the "completion" module. - - * erc-pcomplete.el (pcomplete-erc-nicks): Make sure that we don't - have a nil element in the list when ignore-self is non-nil. - -2006-07-05 Michael Olson - - * erc.el (erc-modules): Use `set' instead of `set-default', since - this setting should never be buffer-local. Add the `page' module - to the list. - - * erc.texi (Modules): Add entries for `list' and `page' modules. - Change "spell" to "spelling". - (History): Use past tense throughout. - -2006-07-02 Michael Olson - - * erc-backend.el (erc-call-hooks): Fix (stringp nil) error that - can happen when doing /PART. - - * erc.el (erc-quit-reason-various-alist) - (erc-part-reason-various-alist): In the example, use "^$" as an - example, since "" matches anything. - (erc-quit-reason-various, erc-part-reason-various): If no argument - is given, and no matches are found, use our default reason instead - of "nil". - -2006-06-30 Michael Olson - - * erc.texi (Modules): Mention identd. - (Releases): Update mailing list address and download location. - (Development): Refactor. Provide updated directions for Arch. - Make URLs clickable. - (Keystroke Summary): Typo fix. Use more Texinfo syntax. - (Getting Started): Give simpler example. We do not need to - explicitly load every module. - (History): Update. - - * erc-autoaway.el, erc-join.el, erc-backend.el, erc-bbdb.el: - erc-button.el, erc-chess.el, erc-compat.el, erc-hecomplete.el: - erc-dcc.el, erc-ezbounce.el, erc-fill.el, erc-ibuffer.el: - erc-imenu.el, erc-list.el, erc-log.el, erc-match.el, erc-menu.el: - erc-networks.el, erc-netsplit.el, erc-nicklist.el: - erc-services.el, erc-pcomplete.el, erc-replace.el, erc-ring.el: - erc-speedbar.el, erc-spelling.el, erc-stamp.el, erc-track.el: - erc.el: Remove version strings. - - * erc.el (erc-cmd-SMV): Remove, since we do not have meaningful - module versions anymore. - (erc-version-modules): Remove, since we do not use this function - anymore. - (erc-latest-version, erc-ediff-latest-version): Remove, since this - was only useful back when ERC consisted of one file. - (erc-modules): Add line for identd. - (erc-get-channel-mode-from-keypress): Typo fix. - - * erc-imenu.el: Remove unnecessary lines in header. - - * erc-goodies.el (erc-handle-irc-url): Docfix. - - * erc-identd.el: Define an ERC module for this. - (erc-identd-start): Don't create a process buffer if possible. - Otherwise, use conventional hidden names for process buffers. - -2006-06-29 Michael Olson - - * erc-backend.el (erc-coding-system-for-target): Match - case-insensitively. Use a pattern match instead of `assoc', as - per the documentation for `erc-encoding-coding-alist'. - - * erc-track.el (erc-track-shorten-aggressively): Fix typo. - -2006-06-27 Michael Olson - - * erc.el: Update maintainer information and URLs. - -2006-06-14 Michael Olson - - * erc.el (erc-active-buffer): If the active buffer has been - deleted, default to the server buffer. - (erc-toggle-flood-control): When the user hits C-c C-f, make flood - control really toggle, not unconditionally turn off. - -2006-06-12 Michael Olson - - * NEWS: Add items since the 5.1.2 release. - - * erc-autoaway.el (erc-autoaway-caused-away): New variable that - indicates whether the current away status was caused by this - module. - (erc-autoaway-set-back): Only set back if this module set the user - away. - (erc-autoaway-set-away): Update `erc-autoaway-caused-away'. - (erc-autoaway-reset-indicators): New function that resets some - indicators when the user is no longer away. - (autoaway): Add the above function to the 305 hook. - -2006-06-05 Romain Francoise - - * erc.texi (History): Fix various typos. - -2006-06-04 Michael Olson - - * erc-autoaway.el (erc-autoaway-idle-method): Move after the - definition of the autoaway module. - (autoaway): Don't do anything if erc-autoaway-idle-method is - unbound. This prevents an error on startup. - -2006-06-03 Michael Olson - - * erc-autoaway.el: Thanks to Mark Plaksin for the ideas and patch. - (erc-autoaway-idle-method): Renamed from - `erc-autoaway-use-emacs-idle'. We have more than two choices for - how to do this, so it's best to make this take symbol values. - Improve documentation. Remove warning against Emacs idle-time; - the point is moot now that we get user idle time via a different - method. Make sure we disable and re-enable the module when - changing this value. - (autoaway): Conditionalize on the above option. If using the idle - timer or user idle methods, don't add anything to the - send-completed or server-001 hooks, since it is unnecessary. - (erc-autoaway-reestablish-idletimer, erc-autoaway-message): - Docfix. - (erc-autoaway-idle-seconds): Use erc-autoaway-idle-method. - (erc-autoaway-reset-idle-irc): Renamed from - `erc-autoaway-reset-idle'. Don't pass line to - `erc-autoaway-set-away', since it is not used. - (erc-autoaway-reset-idle-user): New function that resets the idle - state for user idle time. - (erc-autoaway-set-back): Remove line argument, since it is not - used. - -2006-06-01 Michael Olson - - * erc.el (erc-buffer-filter): Make sure all buffers returned from - this are live. - -2006-05-01 Theresa O'Connor - - * erc-goodies.el (erc-handle-irc-url): New function, suitable as - a value for `url-irc-function'. - -2006-04-18 Diane Murray - - * erc-pcomplete.el (pcomplete-erc-nicks): Added new optional - argument IGNORE-SELF. If this is non-nil, don't return the user's - current nickname. Doc fix. - (pcomplete/erc-mode/complete-command): Don't complete the current - nickname. - -2006-04-05 Diane Murray - - * erc.el (erc-cmd-SV): Removed the exclamation point. Show the - build date as it's shown in `emacs-version'. - - * erc-capab.el (erc-capab-identify-add-prefix): Insert the prefix - with the same face property as the previous character. - -2006-04-02 Michael Olson - - * erc-backend.el, erc-ezbounce.el, erc-join.el, erc-netsplit.el, - erc.el: Make sure to include a newline inside of negated classes, - so that a newline is not matched. - -2006-04-01 Michael Olson - - * erc-backend.el (erc-server-connect-function): Don't try to - detect the existence of the `open-network-stream-nowait' function, - since I can't find it in Emacs21, XEmacs21, or Emacs22. - -2006-03-27 Michael Olson - - * erc.texi: Update direntry. Remove unneeded local variables. - -2006-03-26 Michael Olson - - * erc.el (erc-header-line): New face that will be used to colorize - the text of the header-line, provided that - `erc-header-line-face-method' is non-nil. - (erc-prompt-face): Fix formatting. - (erc-header-line-face-method): New option that determines the - method used for colorizing header-line text. This may be a - function, nil, or non-nil. - (erc-update-mode-line-buffer): Use the aforementioned option and - face to colorize the header-line text, if that is what the user - wants. - (erc-send-input): If flood control is not activated, don't split - the input line. - -2006-03-25 Michael Olson - - * erc.el (erc-cmd-QUOTE): Install patch from Aravind Gottipati - that fixes the case where there is no leading whitespace. Only - remove the first space character, though. - - * erc-identd.el (erc-identd-start): Fix a bug by making sure that - erc-identd-process is set properly. - (erc-identd-start, erc-identd-stop): Add autoload cookies. - (erc-identd-start): Pass :host parameter so this works with Emacs - 22. - -2006-03-09 Diane Murray - - * erc-button.el (erc-button-keymap): Use rather than - for `erc-button-previous' as it is a more standard key - binding for this type of function. - -2006-02-28 Diane Murray - - * erc-capab.el: Removed things that were accidentally committed on - 2006-02-20. Removed Todo section. - (erc-capab-unidentified): Removed. - -2006-02-26 Michael Olson - - * erc-capab.el: Use (eval-when-compile (require 'cl)). - (erc-capab-unidentified): Fix compiler warning by specifying - group. - -2006-02-20 Diane Murray - - * erc-capab.el (erc-capab-send-identify-messages): Fixed comment - to explain thoughts better. `erc-server-parameters' is an - associated list when it's set, not a string. - -2006-02-19 Michael Olson - - * erc-capab.el (erc-capab-send-identify-messages): Make sure some - parameters are strings before using them. Thanks to Alejandro - Benitez for the report. - - * erc.el (erc-version-string): Release ERC 5.1.2. - -2006-02-19 Diane Murray - - * erc-button.el (erc-button-keymap): Bind `erc-button-previous' to - . - (erc-button-previous): New function. - -2006-02-15 Michael Olson - - * NEWS: Add category for ERC 5.2. - - * erc.el (erc): Move to the end of the buffer when a continued - session is detected. Thanks to e1f and indio for the report and - testing a potential fix. - -2006-02-14 Michael Olson - - * debian/changelog: Prepare a new Debian package. - - * Makefile (debprepare): New rule that creates an ERC snapshot - directory for use in both new Debian releases and revisions for - Debian packages. - (debrelease, debrevision-mwolson): Use debprepare. - - * NEWS: Bring up-to-date. - - * erc-stamp.el (erc-insert-timestamp-right): For now, put - timestamps before rather than after erc-fill-column when - erc-timestamp-right-column is nil. This way we won't surprise - anyone unpleasantly, or so it is hoped. - -2006-02-13 Michael Olson - - * erc-dcc.el: Use (eval-when-compile (require 'cl)). - -2006-02-12 Michael Olson - - * erc-autoaway.el, erc-dcc.el, erc-ezbounce.el, erc-fill.el - * erc-goodies.el, erc-hecomplete.el, erc-ibuffer.el, erc-identd.el - * erc-imenu.el, erc-join.el, erc-lang.el, erc-list.el, erc-log.el - * erc-match.el, erc-menu.el, erc-netsplit.el, erc-networks.el - * erc-notify.el, erc-page.el, erc-pcomplete.el, erc-replace.el - * erc-ring.el, erc-services.el, erc-sound.el, erc-speedbar.el - * erc-spelling.el, erc-track.el, erc-truncate.el, erc-xdcc.el: - Add 2006 to copyright years, to comply with the changed guidelines. - -2006-02-11 Michael Olson - - * erc.el (erc-update-modules): Handle erc-capab-identify - correctly. Make some requirements shorter, so that it's easier to - see why they are needed. - - * erc-capab.el: Add autoload cookie for capab-identify. - (erc-capab-send-identify-messages, erc-capab-identify-activate): - Minor whitespace fix in code. - - * erc-stamp.el (erc-timestamp-use-align-to): Renamed from - `erc-timestamp-right-align-by-pixel'. Set the default based on - whether we are in Emacs 22, and using X. Improve documentation. - (erc-insert-aligned): Remove calculation of offset, since - :align-to pos works after all. Unlike the previous solution, this - one works when erc-stamp.el is compiled. - (erc-insert-timestamp-right): Don't add length of string, and then - later remove its displayed width. This puts timestamps after - erc-fill-column when erc-timestamp-right-column is nil, rather - than before it. It also fixes a subtle bug. Remove use of - `current-window', since there is no variable by that name in - Emacs21, Emacs22, or XEmacs21 beta. Check to see whether - `erc-fill-column' is non-nil before using it. - -2006-02-11 Diane Murray - - * erc-list.el: Define `list' module which sets the alias - `erc-cmd-LIST' to `erc-list-channels' when enabled and - `erc-list-channels-simple' when disabled. - (erc-list-channels): Was `erc-cmd-LIST', renamed. - (erc-list-channels-simple): New function. - - * erc.el (erc-modules): Added `list' to enabled modules. Changed - `capab-identify' description. Moved customization options left in - source code. - - * erc-menu.el (erc-menu-definition): Use `erc-list-channels'. - - * erc-capab.el: Put a little more detail into Usage section. - (define-erc-module): Run `erc-capab-identify-setup' in all open - server buffers when enabling. - (erc-capab-identify-setup): Make PROC and PARSED optional - arguments. - (erc-capab-identify-add-prefix): Simplified nickname regexp. This - should now also match nicknames that are formatted differently - than the default. - - * erc-spelling.el (define-erc-module): Make sure there's a buffer - before calling `with-current-buffer'. - -2006-02-10 Michael Olson - - * Makefile (debbuild): Split from debrelease. - (debrevision-mwolson): New rule that causes a Debian revision to - be built. - - * erc.el (erc-migrate-modules): Use a better algorithm. Thanks to - Johan Bockgård. - (erc-modules): Change use of 'pcomplete to 'completion. - -2006-02-09 Diane Murray - - * erc.el (erc-get-parsed-vector, erc-get-parsed-vector-nick) - * erc-capab.el: Require erc. - (erc-capab-send-identify-messages): Use `erc-server-send'. - (erc-capab-identify-remove/set-identified-flag): Use 1 and 0 as - the flags so we can also check whether the `erc-identified' text - property is there at all. - (erc-capab-identify-add-prefix): Use `erc-capab-find-parsed'. - This fixes a bug where the prefix wasn't inserted when timestamps - are inserted on the right. Tweaked nickname regexp. - (erc-capab-find-parsed): New function. - (erc-capab-get-unidentified-nickname): Updated to check for 0 - flag. Only get nickname if there's a nickuserhost associated with - this message. - - * erc-capab.el: New file. Adds the new module - `erc-capab-identify', which allows flagging of unidentified users - on servers running an ircd based on dancer - irc.freenode.net, for - example. - - * erc.el (erc-modules): Added `capab-identify' to options. - (erc-get-parsed-vector, erc-get-parsed-vector-nick) - (erc-get-parsed-vector-type): Moved here from erc-match.el. - - * erc-match.el (erc-get-parsed-vector, erc-get-parsed-vector-nick) - (erc-get-parsed-vector-type): Moved these functions to erc.el - since they can be useful outside of the text matching module. - - * NEWS: Added erc-capab.el. - - * erc-dcc.el, erc-stamp.el, erc-xdcc.el: Changed "Emacs IRC Client" - to "ERC". - -2006-02-07 Michael Olson - - * ChangeLog.01, ChangeLog.02, ChangeLog.03, ChangeLog.04, - ChangeLog.05: Rename from ChangeLog.NNNN in order to disambiguate - the filenames in DOS. - - * erc-goodies.el: Comment fix. - - * erc-hecomplete.el: Rename from erc-complete.el. Update - commentary. Use define-erc-module so that it's possible to - actually use this. - (erc-hecomplete): Rename function from `erc-complete'. - (erc-hecomplete): Rename group from `erc-old-complete'. Docfix. - - * erc-join.el: Rename from erc-autojoin.el. - - * erc-networks.el: Rename from erc-nets.el. - - * erc-services.el: Rename from erc-nickserv.el. - - * erc-stamp.el (erc-insert-aligned): Don't take 3rd argument. Use - the simpler `indent-to' function when - `erc-timestamp-right-align-by-pixel' is nil. - (erc-insert-timestamp-right): If the timestamp goes on the - following line, don't add timestamp properties to the spaces in - front of it. - - * erc.el (erc-migrate-modules): New function that eases migration - of module names. - (erc-modules): Call erc-migrate-modules in the :get accessor. - (erc-modules, erc-update-modules): Update for new modules names. - (erc-cmd-SMV): Remove, since this does not give useful output due - to the version strings being removed from ERC modules. - -2006-02-05 Michael Olson - - * erc-spelling.el (erc-spelling-init): If - `erc-spelling-dictionaries' is nil, do not set - ispell-local-dictionary. Before, it was being set to nil, which - was causing a long delay while the ispell process restarted. - (erc-spelling-unhighlight-word): New function that removes - flyspell properties from a spell-checked word. - (erc-spelling-flyspell-verify): Don't spell-check nicks or words - that have '/' before them. - -2006-02-04 Michael Olson - - * erc-autojoin.el: Use (eval-when-compile (require 'cl)). - - * erc-complete.el (erc-nick-completion-exclude-myself) - (erc-try-complete-nick): Use better function for getting list of - channel users. - - * erc-goodies.el: Docfix. - - * erc-stamp.el: Use new arch tagline, since the other one wasn't - being treated properly. - - * erc.el (erc-version-string): Release ERC 5.1.1. - -2006-02-03 Zhang Wei - - * erc.el (erc-version-string): Don't hard-code Emacs version. - (erc-version): Use emacs-version. - -2006-01-31 Michael Olson - - * erc-stamp.el: Update copyright years. - -2006-01-30 Simon Josefsson - - * erc.el (erc-open-ssl-stream): Use tls.el. - -2006-01-30 Michael Olson - - * erc-stamp.el (erc-timestamp-right-align-by-pixel): New option - that determines whether to use pixel values to align right - timestamps. The default is not to do so, since it only works with - Emacs22 on X, and even then some people have trouble. - (erc-insert-aligned): Use `erc-timestamp-right-align-by-pixel'. - -2006-01-29 Michael Olson - - * ChangeLog, ChangeLog.2005, ChangeLog.2004, ChangeLog.2003, - ChangeLog.2002, ChangeLog.2001: Add "See ChangeLog.NNNN" line for - earlier changes. Use utf-8 encoding. Fix some accent typos. - - * erc-speedbar.el (erc-speedbar-buttons): Fix reference to free - variable. - (erc-speedbar-goto-buffer): Fix compiler warning. - - * erc-ibuffer.el: Use `define-ibuffer-filter' instead of - `ibuffer-define-limiter'. Use `define-ibuffer-column' instead of - `ibuffer-define-column'. Require 'ibuf-ext so that the macros - work without compiler warnings. - - * erc.texi (Obtaining ERC, Installation): Note that these - sections may be skipped if using the version of ERC that comes - with Emacs. - -2006-01-29 Theresa O'Connor - - * erc-viper.el: Remove. Now that ERC is included in Emacs, these - work-arounds live in Viper itself. - -2006-01-28 Michael Olson - - * 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 - - * erc.el (erc-format-message): More `cl' breakage; don't use - `oddp'. - -2006-01-27 Michael Olson - - * 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 - - * 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 Theresa O'Connor - - * 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 - - * 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 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 reusing channel buffers when - automatically re-connecting. Thanks to e1f for noticing. - -2006-01-23 Michael Olson - - * 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 - - * 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 - - * 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 - - * 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 - - * 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 (require '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 - - * erc-backend.el (erc-process-sentinel-1): Remove attempt to - detect SIGPIPE, since it doesn't work. - -2006-01-10 Diane Murray - - * 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 - - * 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 - - * 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. - -2005-11-23 Johan Bockgård - - * erc.el (erc-cmd-SAY): Strip leading space in input line. - -2005-10-29 Michael Olson - - * FOR-RELEASE: Add stuff that needs to be done before the 5.1 - release. Longer-term items can be added to the 5.2 section. - - * Makefile (SITEFLAG): New variable that indicates what variant of - "--site-flag" to use. XEmacs needs "-site-flag". - (INSTALLINFO): New variable indicating how we should call - install-info when installing documentation. - (erc-auto.el, .elc.el): Use $(SITEFLAG). - - * NEWS: Note that last release was 5.0.4. - - * erc.texi: Initial and incomplete draft of ERC documentation. - Commence collaborate-documentation-hack-mode :^) . - -2005-10-29 Diane Murray - - * erc-ring.el (erc-replace-current-command): Revert last change - since it made the prompt disappear when using `erc-next-command' - and `erc-previous-command'. - -2005-10-28 Michael Olson - - * erc.el (erc-input-marker): New variable that indicates the - position where text from the user begins, after the prompt. - (erc-mode-map): Bind to erc-bol, just like C-a. - (erc): Initialize erc-input-marker. - (erc-display-prompt): Even in case where no prompt is desired by - the user, clear the undo buffer and set the input marker. - (erc-bol, erc-user-input): Simplify by using erc-input-marker. - - * erc-pcomplete.el (pcomplete-parse-erc-arguments): Use - erc-insert-marker. - - * erc-ring.el (erc-previous-command) - (erc-replace-current-command): Use erc-insert-marker. - - * erc-spelling.el (erc-spelling-init): Make sure that even Emacs21 - obeys erc-spelling-flyspell-verify. - (erc-spelling-flyspell-verify): Use erc-input-marker. This should - make it considerably faster when switching to a buffer that has - seen a lot of activity since last viewed. - -2005-10-25 Diane Murray - - * erc-backend.el (erc-server-version, 004): Re-added setting of - `erc-server-version'. It doesn't hurt to set, and it could be - used in modules or users' settings. - - * NEWS: Added descriptions of some new features. - -2005-10-20 Diane Murray - - * erc-match.el (erc-current-nick-highlight-type): Set to `keyword' - as default. - (erc-beep-match-types): New variable. - (erc-text-matched-hook): Doc fix. Added `erc-beep-on-match' to - customization options. - (erc-beep-on-match): New function. If the MATCH-TYPE is found in - `erc-beep-match-types', beep. - - * erc-compat.el (erc-make-obsolete, erc-make-obsolete-variable): - New functions to deal with the difference in the number of - arguments accepted by `make-obsolete' and `make-obsolete-variable' - in Emacs and XEmacs. - - * erc.el, erc-nets.el: Use `erc-make-obsolete' and - `erc-make-obsolete-variable'. - - * erc-compat.el (erc-make-obsolete, erc-make-obsolete-variable): - Handle `wrong-number-of-arguments' error instead of checking for - xemacs feature as future versions of XEmacs might accept three - arguments. - -2005-10-18 Theresa O'Connor - - * erc.el: Tell emacs-lisp-mode how to font-lock define-erc-module - docstrings. - -2005-10-08 Diane Murray - - * AUTHORS, CREDITS, ChangeLog, ChangeLog.2002, ChangeLog.2004: - Updated my email address. - -2005-10-06 Michael Olson - - * erc.el (erc-send-input-line, erc-cmd-KICK, erc-cmd-PART) - (erc-cmd-QUIT, erc-cmd-TOPIC, erc-kill-server, erc-kill-channel): - Adapt to new TARGET parameter of erc-server-send. - - * erc-backend.el (erc-server-connect): Don't specify encoding for - erc-server-process, since we set this each time we send a line to - the server. - (erc-encode-string-for-target): Remove. - (erc-server-send): Allow TARGET to be specified. This was how it - used to be before my more-backend work. Set encoding of server - process just before sending text to it. Associate encoding with - text if we are using the queue. - (erc-server-send-queue): Pull encoding from queue. - (erc-message, erc-send-ctcp-message, erc-send-ctcp-notice): Adapt - to new TARGET parameter of erc-server-send. - -2005-10-05 Michael Olson - - * erc.el (erc-toggle-debug-irc-protocol): Use erc-view-mode-enter - rather than view-mode. - - * erc-backend.el (erc-encode-string-for-target): If given a nil or - empty string, return "". - (erc-server-send-queue): XEmacs fix: Use erc-cancel-timer rather - than cancel-timer. - - * erc-compat.el (erc-view-mode-enter): New function that is - aliased to the correct way of entering view-mode. - - * erc-match.el (erc-log-matches-make-buffer): Use - erc-view-mode-enter rather than view-mode-enter. - -2005-10-05 Theresa O'Connor - - * erc-backend.el (erc-encode-string-for-target): If str is nil, - pass the empty string to erc-encode-coding-string instead, which - allows one to /part and /quit without providing a reason again. - -2005-10-03 Michael Olson - - * erc-backend.el (erc-message, erc-send-ctcp-message) - (erc-send-ctcp-notice): Encode string for target before sending. - - * erc.el (erc-cmd-KICK, erc-cmd-PART, erc-cmd-QUIT, erc-cmd-TOPIC) - (erc-kill-server, erc-kill-channel): Ditto. - -2005-09-05 Johan Bockgård - - * erc-page.el (erc-ctcp-query-PAGE): (message text) -> (message - "%s" text). - (erc-cmd-PAGE): Simplify regexp. Put `do-not-parse-args' t. - -2005-09-05 Michael Olson - - * erc.el (erc-flood-limit, erc-flood-limit2): Remove since they - are no longer needed. - (erc-send-input): Detect whether we want flood control to be - active. The previous behavior was to always force the message. - (erc-toggle-flood-control): Adapt to new flood control method. No - more 'strict. - (erc-cmd-SV): Use concat rather than - format-time-string. - (erc-format-target, erc-format-target-and/or-server): Shorten - logic statements. - - * erc-compat.el (erc-emacs-build-time): Use a string - representation rather than trying to coerce a time out of a string - on XEmacs. - - * erc-identd.el (erc-identd-start): Use make-network-process - instead of open-network-stream. Error out if this is not defined. - - * erc-backend.el (erc-send-line): New command that sends a line - using flood control, using a callback for display. It isn't used - yet. - -2005-09-04 Michael Olson - - * erc.el: Add defvaralias and make-obsolete-variable for - erc-default-coding-system. - (channel-topic, channel-modes, channel-user-limit, channel-key, - invitation, away, channel-list, bad-nick): Rename globally to - erc-{name-of-variable}. - -2005-09-03 Johan Bockgård - - * erc.el (erc-message): Simplify regexp. - (erc-cmd-DEOP, erc-cmd-OP): Simplify. - -2005-08-29 Michael Olson - - * erc.el: Alias erc-send-command to erc-server-send. ErBot needs - this to work without modification. Add defvaralias for - erc-process. Make this and the other backwards-compatibility - functions and variables be marked obsolete as of ERC 5.1. - - * erc-backend.el: Add autoload for erc-log macro. - (erc-server-connect): Set some variables before defining process - handlers. It probably doesn't make any difference. - -2005-08-26 Michael Olson - - * erc.el: Add defvaralias for erc-announced-server-name, since - this seems to be widely used. - -2005-08-17 Michael Olson - - * erc.el (erc): Remove unnecessary boundp check. - - * erc-autoaway.el: Fix compiler warning. - - * erc-backend.el (erc-server-version): Since this isn't used by - any code, and isn't generally useful, remove it. - (erc-server-send-queue): Use erc-current-time rather than - float-time. - (004): Don't set erc-server-version. - - * erc-dcc.el (erc-dcc-chat-request, erc-dcc-get-parent): Move to - fix a compiler warning. - - * erc-ibuffer.el (erc-server): Remove unnecessary boundp check. - - * erc-identd.el (erc-identd-start): Use read-string instead of - read-input. - - * erc-imenu.el (erc-unfill-notice): Use a while loop instead of - replace-regexp. - - * erc-nicklist.el: Add conditional dependency on erc-bbdb. - (erc-nicklist-insert-contents): Tighten some regexps. - - * erc-notify.el (erc-notify-list): Docfix. - - * erc-spelling.el (erc-spelling-dictionaries): Add :type and - :group to silence a compiler warning. - -2005-08-14 Michael Olson - - * erc-backend.el (erc-session-server, erc-session-port) - (erc-announced-server-name, erc-server-version) - (erc-server-parameters): Moved here from erc.el. - (erc-server-last-peers): Moved, renamed from last-peers. - (erc-server-lag): Moved, renamed from erc-lag. - (erc-server-duplicates): Moved, renamed from erc-duplicates. - (erc-server-duplicate-timeout): Moved, renamed from - erc-duplicate-timeout. - (erc-server): New customization group hosting all options from - this file. - (erc-server-prevent-duplicates): Moved, renamed from - erc-prevent-duplicates. - (erc-server-duplicate-timeout): Moved, renamed from - erc-duplicate-timeout. - (erc-server-auto-reconnect, erc-split-line-length) - (erc-server-coding-system, erc-encoding-coding-alist) - (erc-server-connect-function, erc-server-flood-margin) - (erc-server-flood-penalty): Change group to 'erc-server. - (erc-server-send-ping-interval): Moved, renamed from - erc-ping-interval. - (erc-server-ping-handler): Moved, renamed from erc-ping-handler. - (erc-server-setup-periodical-server-ping): Moved, renamed from - erc-setup-periodical-server-ping. - (erc-server-connect): Add to docstring. Move more initialization - here. - (erc-server-processing-p): Docfix. - (erc-server-connect): Use 'raw-text like in the original version. - (erc-server-filter-function): Don't reset process coding system. - - * erc-stamp.el (erc-add-timestamp): If the text at point is - invisible, don't insert a timestamp. Thanks to Pascal - J. Bourguignon for the suggestion. - - * erc-match.el (erc-text-matched-hook): Don't hide fools by - default, but include it in the available options. - -2005-08-13 Michael Olson - - * erc-*.el: s/erc-send-command/erc-server-send/g. - s/erc-process/erc-server-process/g (sort of). Occasional - whitespace and indentation fixes. - - * erc-backend.el: Specify a few local variables for indentation. - Take one item off of the TODO list. - (erc-server-filter-data): Renamed from erc-previous-read. From - circe. - (erc-server-processing-p): New variable that indicates when we're - currently processing a message. From circe. - (erc-split-line-length): New option that gives the maximum line - length of a single message. From circe. - (erc-default-coding-system): Moved here from erc.el. - (erc-split-line): Renamed from erc-split-command and taken from - circe. - (erc-connect-function, erc-connect, erc-process-sentinel-1) - (erc-process-sentinel, erc-flood-exceeded-p, erc-send-command) - (erc-message, erc-upcase-first-word, erc-send-ctcp-message) - (erc-send-ctcp-notice): Moved here from erc.el. - (erc-server-filter-function): Renamed from erc-process-filter. - From circe. - (erc-server-process): Renamed from `erc-process' and moved here - from erc.el. - (erc-server-coding-system): Renamed from - `erc-default-coding-system'. - (erc-encoding-coding-alist): Moved here from erc.el. - (erc-server-flood-margin, erc-server-flood-penalty): - (erc-server-flood-last-message, erc-server-flood-queue): - (erc-server-flood-timer): New options from circe that allow - tweaking of flood control. - (erc-server-connect-function): Renamed from erc-connect-function. - (erc-flood-exceeded-p): Removed. - (erc-coding-system-for-target) - (erc-encode-string-for-target, erc-decode-string-from-target): - Moved here from erc.el - (erc-server-send): Renamed from erc-send-command. Adapted from - the circe function by the same name. - (erc-server-send-queue): New function from circe that implements - handling of a flood queue. - (erc-server-current-nick): Renamed from current-nick. - (erc-server-quitting): Renamed from `quitting'. - (erc-server-last-sent-time): Renamed from `last-sent-time'. - (erc-server-last-ping-time): Renamed from `last-ping-time'. - (erc-server-lines-sent): Renamed from `lines-sent'. - (erc-server-auto-reconnect): Renamed from `erc-auto-reconnect'. - (erc-server-coding-system): Docfix. - (erc-server-connect): Renamed from `erc-connect'. Require SERVER - and PORT parameters. Initialize several variables here. Don't - set `erc-insert-marker'. Use a per-server coding system via - erc-server-default-encoding. - - * erc.el (erc-version-string): Changed to indicate we are running - the `more-backend' branch. - (erc-send-single-line): Implement flood control using - erc-split-line. - (erc-send-input): Move functionality of erc-send-single-line in - here. - (erc-send-single-line): Assimilated! - (erc-display-command, erc-display-msg): Handle display hooks. - (erc-auto-reconnect, current-nick, last-sent-time) - (last-ping-time, last-ctcp-time, erc-lines-sent, erc-bytes-sent) - (quitting): Moved to erc-backend.el. - (erc): Docfix. Don't initialize quite so many things here. - -2005-08-10 Michael Olson - - * debian/copyright (Copyright): Remove notices for 4 people, since - they didn't contribute legally-significant changes, or have had - these changes overwritten. - - * erc-log.el: Remove copyright notice. - - * erc.el: Remove 3 copyright notices. - -2005-08-09 Michael Olson - - * debian/changelog: Create 5.0.4-3 package. This doesn't serve - any purpose other than to thank Romain Francoise for some advice. - - * Makefile (debrelease): Allow last upload and extra build options - to be specified. - -2005-08-08 Michael Olson - - * debian/changelog: Create 5.0.4-2 package. - - * debian/control (Uploaders): Add Romain Francoise. - (Standards-Version): Update to 3.6.2. - (Depends): Add `emacsen'. - - * debian/scripts/startup.erc (load-path): Minor whitespace fixup. - - * Makefile (clean): Split target from realclean and make it remove - files that aren't packaged in releases. - (clean, release): Minor cleanups. - (debrelease): Use debuild rather than dpkg-buildpackage since the - former calls lintian. Minor cleanups. - (debrelease-mwolson): New target that removes old Debian packages, - calls debrelease, and copies the resulting package to my dist dir. - (upload): New target that automates the process of uploading an - ERC release to sourceforge. - - * erc.el (erc-mode): Use `make-local-variable' instead of - `make-variable-buffer-local'. - -2005-07-12 Michael Olson - - * debian/changelog: Build 5.0.4-1. - - * Makefile (release): Prepare zip file in addition to tarball. - - * NEWS: Add item for the undo fix. - -2005-07-09 Michael Olson - - * erc-nicklist.el (erc-nicklist-insert-contents): Check - erc-announced-name before erc-session-server. Make sure that we - can never get a stringp (nil) error. - (erc-nicklist-call-erc-command): If given no command, do nothing. - This fixes an error that used to occur when a stray mouse click - was made outside of the popup window, but on the erc-nicklist - menu. - - * erc-bbdb.el (erc-bbdb-search-name-and-create): Get rid of the - infinite input loop when you want to create a new record. Replace - most of that with a completing read of existing nicks. If no nick - is chosen, create a new John Doe record. The net effect of this - is that the old behavior is re-instated, with the addition of one - completing read that happens when you do a /whois. - -2005-07-09 Johan Bockgård - - * erc.el (erc-process-input-line): Docfix. - (erc-update-mode-line-buffer): Use `erc-propertize' instead of - `propertize'. - (erc-propertize): Move to erc-compat.el. - - * erc-compat.el (erc-propertize): Move here from erc.el. Always - return a copy of the string (like `propertize' in GNU Emacs). - - * erc-nicklist.el (erc-nicklist-icons-directory) - (erc-nicklist-voiced-position) - (erc-nicklist-insert-medium-name-or-icon): Docfix. - (erc-nicklist-insert-contents): Simplify. - (erc-nicklist-mode-map): Bind RET instead of `return'. Bind - `down-mouse-3' instead of `mouse-3'. - (erc-nicklist-kbd-cmd-QUERY): Cleanup regexp. - (erc-nicklist-channel-users-info): Docfix. Simplify. - -2005-07-02 Michael Olson - - * images: New directory containing the images that are used by - erc-nicklist.el. These are from Gaim, and are thought to be - available under the terms of the GPL. - - * erc-bbdb.el: Add local variables section to preserve tabs, since - that is the style used throughout this file. Apply patch from - Edgar Gonçalves as follows. - (erc-bbdb-bitlbee-name-field): New variable that indicates the - field name to use for annotating the "displayed name" of a bitlbee - contact. - (erc-bbdb-irc-highlight-field): Docfix. - (erc-bbdb-search-name-and-create): Prompt the user for the name of - a contact if none was found. Merge the new entries into the - specified contact. If new arg SILENT is non-nil, do not prompt - the user for a name or offer to merge the new entry. - (erc-bbdb-insinuate-and-show-entry): New arg SILENT is accepted, - which is passed on to erc-bbdb-search-name-and-create. - (erc-bbdb-whois): Tell erc-bbdb-search-name-and-create to prompt - for name if necessary. - (erc-bbdb-JOIN, erb-bbdb-NICK): Forbid - erc-bbdb-search-name-and-create from prompting for a name. - - * erc-nicklist.el: Add local variables section to preserve tabs, - since that is the style used throughout this file. Apply patch - from Edgar Gonçalves as follows. - (erc-nicklist-use-icons): New option; if non-nil, display an icon - instead of the name of the chat medium. - (erc-nicklist-icons-directory): New option indicating the path to - the PNG files that are used for chat icons. - (erc-nicklist-use-icons): New option indicating whether to put - voiced nicks on top, bottom, or not to differentiate them. The - default is to put them on the bottom. - (erc-nicklist-bitlbee-connected-p): New variable that indicates - whether or not we are currently using bitlbee. An attempt will be - made to auto-detect the proper value. This is bound in the - `erc-nicklist-insert-contents' function. - (erc-nicklist-nicklist-images-alist): New variable that maps a - host type to its icon. This is set by `erc-nicklist'. - (erc-nicklist-insert-medium-name-or-icon): New function that - inserts an icon or string that identifies the current host type. - (erc-nicklist-search-for-nick): New function that attempts to find - a BBDB record that corresponds with this contact given its - finger-host. If found, return its bitlbee-nick field. - (erc-nicklist-insert-contents): New function that inserts the - contents of the nick list, including text properties and images. - (erc-nicklist): Populate `erc-nicklist-images-alist'. Move - nicklist content generation code to - `erc-nicklist-insert-contents'. - (erc-nicklist-mode-map): Map C-j to erc-nicklist-kbd-menu and RET - to erc-nicklist-kbd-cmd-QUERY. - (erc-nicklist-call-erc-command): Make use of - `switch-to-buffer-other-window'. - (erc-nicklist-cmd-QUERY): New function that opens a query buffer - for the given contact. - (erc-nicklist-kbd-cmd-QUERY): Ditto; contains most of the code. - (erc-nicklist-kbd-menu): New function that shows the nicklist - action menu. - (erc-nicklist-channel-users-info): Renamed from - `erc-nicklist-channel-nicks'. Implement sorting voiced users. - -2005-06-29 Johan Bockgård - - * erc-nickserv.el (erc-nickserv-alist): Fix regexp for Azzurra. - -2005-06-26 Michael Olson - - * erc-autojoin.el (erc-autojoin-add, erc-autojoin-remove): Use - `erc-session-server' if `erc-announced-server-name' is nil. This - happens when servers don't send a 004 message. - - * erc.el (erc-quit-server): Ditto. - - * erc-ibuffer.el (erc-server, erc-server-name): Ditto. - - * erc-notify.el (erc-notify-JOIN, erc-notify-NICK) - (erc-notify-QUIT): Ditto. - -2005-06-24 Johan Bockgård - - * erc.el (erc-default-coding-system) - (erc-handle-user-status-change): Docstring fix. - (with-erc-channel-buffer): Removed. - (erc-ignored-reply-p): Replace `with-erc-channel-buffer' with - `erc-with-buffer'. - (erc-display-line-1): Fix broken undo. - -2005-06-23 Michael Olson - - * CREDITS: Add entries for Luigi Panzeri and Andreas Schwab. - - * erc-nickserv.el (erc-nickserv-alist): Add entries for Azzurra - and OFTC. Thanks to Luigi Panzeri and Andreas Schwab for - providing these. - -2005-06-16 Michael Olson - - * CREDITS: Add John Paul Wallington. - - * erc.el: Thanks to John Paul Wallington for the following. - (erc-nickname-in-use): Use `string-to-number' instead of - `string-to-int'. - - * erc-dcc.el (erc-dcc-handle-ctcp-send) - (erc-dcc-handle-ctcp-chat, erc-dcc-get-file) - (erc-dcc-chat-accept): Ditto. - - * erc-identd.el (erc-identd-start): Ditto. - -2005-06-16 Johan Bockgård - - * erc.el (erc-mode-map): Suppress `font-lock-fontify-block' key - binding since it destroys face properties. - -2005-06-08 Michael Olson - - * erc.el (erc-cmd-UNIGNORE): Use `erc-member-ignore-case' instead - of `member-ignore-case'. Thanks to bpalmer for the heads up. - -2005-06-06 Michael Olson - - * erc.el (erc-modules): Fix a mistake I made when editing this a - few days ago. Modes should now be disabled properly. - (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Remove unnecessary call to - `format'. Thanks to Andreas Schwab for reporting this. - - * debian/changelog: Close "README file missing" bug. - - * debian/rules (binary-erc): Install README file. - -2005-06-03 Michael Olson - - * erc.el (erc-with-buffer): Set `lisp-indent-function' so Emacs - Lisp mode knows how to indent erc-with-buffer blocks. - (with-erc-channel-buffer): Ditto. - (erc-with-all-buffers-of-server): Ditto. - (erc-modules): Use pcomplete by default, not completion, since - erc-complete.el is deprecated. Use `fboundp' instead of - `symbol-value' to check for existence of a function before calling - it. This was causing an error when untoggling the `completion' - option and trying to save via the customize interface. - - * erc-track.el (erc-modified-channels-update): If a buffer is not - currently connected, remove it from the modified channels list. - This should fix the problem where residue was left on the mode - line after quitting ERC. - - * erc-list.el (erc-prettify-channel-list): Docfix; thanks to John - Paul Wallington for reporting this. - -2005-05-31 Michael Olson - - * debian/changelog: First draft of entries for the 5.0.3 release. - - * debian/README.Debian: Note that ERC will now install correctly - on versions of Emacs or XEmacs that do not have the `format-spec' - library. Correct some grammar and prune the content a bit. - - * debian/scripts/install (emacs20): Remove line since we no longer - need to deal with format-spec.el. - - * NEWS: Add entries for the upcoming 5.0.3 release. - - * erc.el: Don't require format-spec since this is provided in - erc-compat.el now. - (erc-process-sentinel, erc-setup-periodical-server-ping): Use - `erc-cancel-timer' instead of `cancel-timer'. - (erc-version-string): Update to 5.0.3. - - * erc-autoaway.el (autoaway, erc-autoaway-reestablish-idletimer): - Use `erc-cancel-timer' instead of `cancel-timer'. - - * erc-compat.el (format-spec, format-spec-make): If we cannot load - the `format-spec' library, provide versions of these functions. - This should keep problems from surfacing with Emacs21 Debian - builds. - (erc-cancel-timer): New function created to take the place of - `cancel-timer' since XEmacs calls it something else. - - * erc-track.el (erc-modified-channels-update): Accept any number - of arguments, which are ignored. This allows it to be run from - `erc-disconnected-hook' without extra bother. - (track): Add `erc-modified-channels-update' to - `erc-disconnected-hook' so that the indicators are removed - correctly in some edge cases. - (erc-modified-channels-display): Make sure that we never pass nil - to the function in `erc-track-shorten-function'. This happens - when we have deleted buffers in `erc-modified-channels-alist'. - Also, make sure that the buffer has a non-nil short-name before - adding it to the string list. This should fix some XEmacs - warnings when running /quit with unchecked buffers, as well as get - rid of a stray buffer problem (or so it is hoped). - -2005-05-31 Johan Bockgård - - * erc-replace.el, erc-speak.el: Clean up comment formatting. - - * erc-ring.el (ring, erc-input-ring-index, erc-clear-input-ring): - Clean up docstring formatting. - -2005-05-30 Johan Bockgård - - * erc.el (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Delete superfluous - arg to `format'. - (erc-load-irc-script): Use `insert-file-contents' instead of - `insert-file'. Simplify. - -2005-05-29 Michael Olson - - * erc.el (erc-version-string): Move this up so that it is - evaluated before the `require' statements. Not a major change. - -2005-04-27 Johan Bockgård - - * erc.el (erc-complete-word): Simplify. - -2005-04-27 Michael Olson - - * Makefile (debrelease): Use a slightly different approach when - removing CVS and Arch cruft. - - * debian/changelog: Update for 5.0.2-1 package. - -2005-04-25 Michael Olson - - * erc-autoaway.el (erc-autoaway-reestablish-idletimer): Move code - block higher in file to fix a load failure when using Emacs21. - Thanks to Daniel Brockman for the report and fix. - -2005-04-24 Adrian Aichner - - * erc-backend.el (JOIN): save-excursion so that - `erc-current-logfile' inserts into the correct channel buffers - when using erc-log-insert-log-on-open in combination with autojoin - to multiple channels. - -2005-04-17 Adrian Aichner - - * erc-log.el: Remove stray whitespace. - * erc.el: Ditto. - -2005-04-09 Aidan Kehoe - - * erc.el: autoload erc-select-read-args, which, because it parses - erc-select's args, can be called before erc.el is loaded. - -2005-04-07 Theresa O'Connor - - * erc-viper.el: Remove final newlines from previously-existing ERC - buffers. (Minor bug fix.) - -2005-04-06 Michael Olson - - * Makefile (debrelease): Ignore errors from deleting Arch and CVS - metadata. - -2005-04-05 Michael Olson - - * ChangeLog, CREDITS, AUTHORS: Correct name and email address of - Marcelo Toledo. - -2005-04-04 Michael Olson - - * erc.el (erc-modules): Add entry for spelling module. - - * erc-spelling.el: Add autoload line. - - * erc-backend.el: Apply latest non-ascii patch from Kai Fan. - (erc-decode-parsed-server-response): Search - erc-response.command-args for channel name. Decode the - erc-response struct using this channel name as key according to - the `erc-encoding-coding-alist'. - - * erc-track.el: Apply patch from Henrik Enberg. - (erc-modified-channels-object): Use optimal amount of whitespace - around modified channels indicator. - -2005-04-02 Johan Bockgård - - * erc.el (define-erc-module, erc-with-buffer) - (erc-with-all-buffers-of-server, with-erc-channel-buffer): Add - edebug-form-spec. - - * erc-compat.el (erc-define-minor-mode): Ditto. - -2005-03-29 Jorgen Schaefer - - * erc-spelling.el: New file. - -2005-03-24 Johan Bockgård - - * erc-backend.el (define-erc-response-handler): Add - `definition-name' property to constructed symbols so that - find-function and find-variable will find them. - -2005-03-21 Michael Olson - - * erc-dcc.el, erc-goodies.el, erc-list.el, erc-notify.el, - erc-ring.el, erc.el: Copyright assignment occurred. - - * debian/scripts/install: Make a shell wrapper around the original - Makefile and inline the Makefile. The problem is that Debian - passes all the Emacs variants at once, rotating them at every - invocation of the install script, which happens once per variant. - This caused each installation to happen N-1 times more often than - it should have. As a result, we need to only deal with the first - argument. - (ELFILES): Only add format-spec.el if we are compiling for - emacs21. Don't filter out erc-compat.el. - (SITEFLAG): New variable that indicates that the "nosite" option - should look like. - (.DEFAULT): Use $(FLAVOUR) instead of $@ for clarity. - - * debian/rules: Install NEWS file and compress it. - - * debian/maint/postinst: Be more cautious about configuration - step. - - * debian/copyright (Copyright): Another assignment came in. - - * debian/control (Standards-Version): Update to a newer version as - recommended by lintian. - - * debian/changelog: Changes made for the Debian package. - - * debian/README.Debian: Keep only the General Notes section. - - * NEWS: Move old history items here from debian/README.Debian. - - * Makefile (SNAPSHOTDATE): Deprecate this option since we hope to - release more often. - -2005-03-20 Jorgen Schaefer - - * erc.el (erc-define-catalog, `ctcp-request-to'): Fix typo (%: -> - %t:). - -2005-03-01 Michael Olson - - * erc-log.el (erc-save-buffer-in-logs): Replace tabs with spaces - in code indentation. - -2005-02-28 Michael Olson - - * erc.el (erc-display-message): Apply corrected patch from Henrik - Enberg. - -2005-02-27 Michael Olson - - * erc.el (erc-display-message): Apply patch from Henrik Enberg. - Check here to see if a message should be hidden, rather than - relying on code in each individual command. - (erc-version-string): Add "(CVS)" to the version string for - clarity. - - * erc-backend.el (JOIN, KICK, MODE, NICK, PART, QUIT, TOPIC): - Don't check `erc-hide-list' here. - - * erc-list.el, erc-match.el, erc.el, debian/copyright: Update - copyright information as a few more people have assignments - registered. - -2005-02-06 Michael Olson - - * erc-backend.el: Apply patch from Kai Fan for non-ASCII character - support. - (erc-parse-server-response): Add call to - `erc-decode-parsed-server-response'. - (erc-decode-parsed-server-response): New function that decodes a - pre-parsed server response before it can be handled. - (PRIVMSG): Comment out call to `erc-decode-string-from-target'. - (TOPIC): Ditto. - -2005-02-01 Jorgen Schaefer - - * erc.el (erc-process-sentinel-1): Don't reconnect on connection - refused. This error is reported differently when using - open-network-stream-nowait. - -2005-01-26 Diane Murray - - * erc.el (erc-cmd-APPENDTOPIC, erc-set-topic): The control - character in `channel-topic' was changed to \C-o - replaced \C-c - with \C-o so that these functions work as expected again. - (erc-get-channel-mode-from-keypress): Doc fix. - -2005-01-25 Diane Murray - - * erc.el, erc-button.el, erc-compat.el, erc-goodies.el, - erc-match.el, erc-nets.el, ChangeLog, NEWS: Merged bug fixes made - on release_5_0_branch since 5.0.1 release. - -2005-01-24 Johan Bockgård - - * erc.el (erc-input-action): Quote `erc-action-history-list' so - that input history actually works. - (erc-process-ctcp-query): Fix and simplify logic. - (erc-get-channel-mode-from-keypress): Use `C-' string syntax. - (erc-load-irc-script-lines): Use `erc-command-indicator' instead - of `erc-prompt'. - -2005-01-23 Theresa O'Connor - - * erc-viper.el: Ensure that `viper-comint-mode-hook' runs in - buffers whose `erc-mode-hook' has already run when this file is - loaded. - Explicitly `require' erc.el. - -2005-01-22 Theresa O'Connor - - * erc.el (erc-mode): Remove frobbing of `require-final-newline'. - - * erc-log.el (erc-save-buffer-in-logs): Remove frobbing of - `require-final-newline'. - - * erc-viper.el: New file. This is where all ERC/Viper - compatibility code should live. When and if ERC is bundled with - Emacs, some of the hacks in this file should be merged into Viper - itself. - -2005-01-21 Theresa O'Connor - - * erc.el (erc-mode): Set `require-final-newline' to nil in ERC - buffers. This prevents a Viper misfeature whereby extraneous - newlines are inserted into the ERC buffer when switching between - viper states. - - * erc-log.el (erc-save-buffer-in-logs): Bind `require-final-newline' - to t when calling `write-region' to ensure that further log - entries start on fresh lines. - -2005-01-21 Diane Murray - - * erc-button.el (erc-button-add-face): Reverted my change to the - order faces since it had the unwanted effect of putting the button - face after all others. - (erc-button-face-has-priority): Removed this variable as it is not - necessary anymore - it was used to compensate for the above - mentioned change. - - * NEWS: Added the latest fixes. - -2005-01-20 Diane Murray - - * erc-button.el, erc-match.el: - (erc-button-syntax-table, erc-match-syntax-table): Added \ as a - legal character for nicknames. - - * erc-nets.el (erc-server-select): Fixed so that only networks - with servers found in `erc-server-alist' are available as choices. - - * erc.el, erc-compat.el, erc-goodies.el: - (erc-replace-match-subexpression-in-string): New function. Needed - because `replace-match' in XEmacs doesn't replace regular - expression subexpressions in strings, only in buffers. - (erc-seconds-to-string, erc-controls-interpret): Use the new - function. - - * erc-button.el (erc-button-add-button): Use the `:button-face' - key combined with an `erc-mode' local `widget-button-face' set to - nil to get the widget overlay face suppressed in XEmacs. - -2005-01-19 Francis Litterio - - * erc-button.el (erc-button-add-face): The face added by this - function is more important than the existing text's face, so we - now prepend erc-button-face to the list of existing faces when - adding a button. To instead append erc-button-face to existing - faces, set variable `erc-button-face-has-priority' to nil. - (erc-button-face-has-priority): New variable to control how - erc-button-add-face adds erc-button-face to existing faces. - (erc-button-press-button): Silenced a byte-compiler warning about - too few arguments in a call to `error'. - -2005-01-19 Diane Murray - - * NEWS: Added list of 5.0.1 fixes. - -2005-01-19 Michael Olson - - * AUTHORS: Move to format that cscvs can understand. As an added - perk, entries line up nicer. - - * erc.el, erc-fill.el, erc-pcomplete.el, debian/copyright: Merge a - few more copyright lines thanks to Alex Schroeder's BBDB file. - - * Makefile: Change version to correspond with our new scheme. - -2005-01-18 Diane Murray - - * erc-list.el (erc-chanlist-channel-line-regexp): Now matches - private channels, the channels `#' and `&', and channels with - names including non-ascii characters. - (erc-chanlist-join-channel): Don't attempt to join private - channels since the channel name is unknown. - - * erc-goodies.el (erc-make-read-only): Add `rear-nonsticky' - property to avoid `Text is read-only' errors during connection. - `front-nonsticky' does not exist, changed to `front-sticky'. - (erc-controls-interpret, erc-controls-strip): Just work on the - string, don't open a temporary buffer. - (erc-controls-propertize): Now accepts optional argument STR. - -2005-01-17 Michael Olson - - * Makefile: Version is 5.01, but only in the Makefile. It has not - been released yet. - - * erc-auto.in, erc-autojoin.el, erc-bbdb.el, erc-button.el, - erc-chess.el, erc-complete.el, erc-dcc.el, erc-fill.el, - erc-goodies.el, erc-ibuffer.el, erc-identd.el, erc-imenu.el, - erc-list.el, erc-match.el, erc-menu.el, erc-nets.el, - erc-netsplit.el, erc-nickserv.el, erc-notify.el, erc-pcomplete.el, - erc-ring.el, erc-speak.el, erc-speedbar.el, erc-stamp.el, - erc-track.el, erc-xdcc.el, erc.el, debian/copyright: Update - copyright notices. If anyone has signed papers for Emacs in - general, merge them with the FSF's entry. - -2005-01-16 Diane Murray - - * erc.el (erc): `erc-set-active-buffer' was being called before - `erc-process' was set, so that channels weren't being marked - active correctly upon join; fixed. - -2005-01-15 Johan Bockgård - - * erc-backend.el (def-edebug-spec): This macro caused problems (in - XEmacs). Use its expansion directly. - -2005-01-15 Diane Murray - - * erc-button.el (erc-button-add-button): Reverted previous change - since `:suppress-face' doesn't seem to be checked for a certain - face. - (erc-button-add-face): FACE is now appended to the `old' face. - This should fix the problem of faces being "covered" by - `erc-button-face'. - -2005-01-14 Diane Murray - - * erc.el, erc-backend.el (erc-cmd-OPS, erc-cmd-COUNTRY, - erc-cmd-NICK, erc-process-ctcp-query, ERROR, PONG, 311, 312, 313, - 314, 317, 319, 320, 321, 322, 330, 352): Use catalog entries - instead of hard-coded text messages. - (english): Added new catalog entries `country', `country-unknown', - `ctcp-empty', `ctcp-request-to', `ctcp-too-many', `nick-too-long', - `ops', `ops-none', `ERROR', `PONG', `s311', `s312', `s313', - `s314', `s317', `s317-on-since', `s319', `s320', `s321', `s322', - `s330', and `s352'. - (erc-send-current-line): Use `erc-set-active-buffer' (change was - lost in previous bug fix). - -2005-01-14 Francis Litterio - - * erc-button.el (erc-button-add-button): Fixed a bug where the - overlay created by widget-convert-button has a `face' property - that hides the `face' property set on the underlying button text. - - * erc-goodies.el: Docstring fix. - - * erc-button.el: Improved docstring for variable erc-button-face. - -2005-01-13 Diane Murray - - * erc-menu.el (erc-menu-definition): "Topic set by channel - operator": Small word change. "Identify to NickServ...": Check - that we're connected to the server. Added "Save buffer in log" - and "Truncate buffer". - -2005-01-13 Lawrence Mitchell - - * erc.el (erc-display-line-1): Widen before we try to insert - anything, this makes sure input isn't broken when the buffer is - narrowed by the user. - (erc-beg-of-input-line): Simplify, just return the position of - `erc-insert-marker' or error if does not exist. - (erc-send-current-line): Widen before trying to send anything. - -2005-01-13 Diane Murray - - * erc.el, erc-backend.el, erc-list.el: - (erc-update-mode-line-buffer): Strip controls characters from - `channel-topic' since we add our own control character to it. - (TOPIC, 332): Use \C-o instead of \C-c to force an end of IRC - control characters as it also ends bold, underline, and inverse - - \C-c only ends colors. - (erc-chanlist-322): Strip control characters from channel and - topic. No need to interpret controls when we're applying overlays - to the lines. - - * erc.el, erc-backend.el, erc-button.el, erc-netsplit.el, - erc-nicklist.el: Fixed so that each server has an active buffer. - (erc-active-buffer): Now a buffer-local variable. - (erc-active-buffer, erc-set-active-buffer): New functions. - (erc-display-line, erc-echo-notice-in-active-non-server-buffer, - erc-process-away, MODE): Call `erc-active-buffer' to get the - active buffer for the current server. - (erc, erc-process-sentinel-1, erc-grab-region, erc-input-action, - erc-send-current-line, erc-invite-only-mode, - erc-toggle-channel-mode, erc-channel-names, MODE, erc-nick-popup, - erc-nicklist-call-erc-command): Use `erc-set-active-buffer' to set - the active buffer for the current server. - (erc-cmd-WHOLEFT): Use 'active as BUFFER in `erc-display-message'. - - * erc-track.el (erc-track-modified-channels): Server buffers are - now treated the same as channels and queries. This means that - `erc-track-priority-faces-only', `erc-track-exclude', and - `erc-track-exclude-types' now work with server buffers. - -2005-01-12 Diane Murray - - * erc-backend.el (475): Prompt for the channel's key if - `erc-prompt-for-channel-key' is non-nil. Send a new JOIN message - with the key if a key is provided. - - * erc.el (erc-command-indicator): Fixed customization choices so - that there's no `mismatch' message when nil is the value. - -2005-01-11 Michael Olson - - * erc-bbdb.el (bbdb): Lowercase the name of the module. This - fixes a bug which caused an error to occur when trying to enable - the module using the customization interface. - -2005-01-08 Theresa O'Connor - - * erc-track.el: Support using faces to indicate channel activity - in the modeline under XEmacs. - (erc-modified-channels-object): New function. - (erc-modified-channels-display): Use it. - `erc-modified-channels-string' renamed to - `erc-modified-channels-object' (because it's no longer a string on - XEmacs). The new function `erc-modified-channels-object' is used - to generate updated values for the same-named variable. - -2005-01-08 Diane Murray - - * ChangeLog.2002: Changed instances of my sourceforge username and - email address to real name and email. - - * erc.el (erc-modules): Changed customization tag descriptions, so - that they all start with a verb; added new modules to choices. - -2005-01-08 Mario Lang - - * debian/rules: Introduce new variable DOCDIR to simplify stuff a - bit. - -2005-01-08 Michael Olson - - * AUTHORS, ChangeLog.2004: Change bpalmer's email address as - requested. - - * CREDITS: Add everyone who is mentioned in the ChangeLogs. - - * debian/copyright (Copyright): Add last few people. This can now - be considered a complete list, as far as CVS entries are - concerned. If people have assigned copyright to the FSF, merge - them with the entry for the FSF. - - * debian/README.Debian: Add entry for XEmacs-related change in - `erc-track.el'. - - * erc.el (erc-cmd-MODE): New command that changes or displays the - mode for a channel or user. The functionality was present before - this change, but there was no documentation for it. - - * erc-auto.in, erc-*.el: Fully investigate copyright headers and - change them appropriately. If a file has been pulled off of - erc.el at one time, keep track of copyright from the time of - separation, but not before. If a file has been derived from a - work outside of erc, keep copyright statements in place. - - * Makefile (VERSION): Change to 5.0! :^) Congrats on all the great - work. I'll wait until hober commits his XEmacs compatibility - patch to erc-track.el, and then release. - (distclean): Alias for `realclean' target. - -2005-01-07 Michael Olson - - * AUTHORS: Add Marcelo Toledo, who has CVS access to this project. - - * ChangeLog.2004: Add my name to my one contribution to erc last - year. - - * CREDITS: Add people that were discovered while scouring - ChangeLogs. - - * debian/copyright: Add everyone from `AUTHORS' to Upstream - Authors. Anyone who has contributed 15 or more lines of - code (according to ChangeLogs) is listed in Copyright section. - Accurate years are included. - - * debian/README.Debian: Paste content of NEWS and reformat - slightly. - - * debian/rules: Concatenate the ChangeLogs during the Debian - install process and then gzip them. - - * Makefile (MISC): Add ChangeLog.yyyy files to list. - (ChangeLog): Remove rule since we do not dynamically generate the - ChangeLog anymore. - - * MkChangeLog: Removed since we do not use it to generate the - ChangeLog anymore. cvs2cl does a much better job anyway. - - * NEWS: Use 3rd level heading instead of bullets for lists that - contain descriptions. - -2005-01-07 Diane Murray - - * erc-list.el: Require 'sort. - (erc-chanlist): Disable undo in the channel list buffer. - - * erc.el, erc-menu.el: The `IRC' menu is now automatically added - to the menu-bar. Add the call to `easy-menu-add' to - `erc-mode-hook' when running in XEmacs (without this the menu - doesn't appear). - - * NEWS: Added the information from - https://emacswiki.org/cgi-bin/wiki/ErcCvsFeatures and the newer - changes which weren't yet documented on that page. - -2005-01-06 Hoan Ton-That - - * erc-log.el (erc-current-logfile): Only downcase the logfile - name, not the whole filename. Also expand relative to - `erc-log-channels-directory'. - (erc-generate-log-file-name-with-date) - (erc-generate-log-file-name-short) - (erc-generate-log-file-name-long): Don't expand filename, done in - `erc-current-logfile'. - -2005-01-06 Lawrence Mitchell - - * NEWS: New file, details user visible changes from version to - version. - - * HACKING (NEWS entries): Mention NEWS file, and what its purpose - is. - -2005-01-05 Michael Olson - - * FOR-RELEASE: New file containing the list of release-critical - tasks. Feel free to add to it. - - * debian/rules (binary-erc): Add ChangeLog files. - -2005-01-04 Michael Olson - - * ChangeLog.2001, ChangeLog.2002, ChangeLog.2003, ChangeLog.2004: - ChangeLog entries from previous years. - - * ChangeLog: New file containing ChangeLog entries for the current - year. Please update this file manually whenever a change is - committed. This is a new policy. - - * AUTHORS: Add myself to list. Some entries were space-delimited - instead of TAB-delimited, and since the latter seemed to be the - default, make the other entries conform. - - * HACKING (ChangeLog Entries): Update section to reflect new - policy toward ChangeLog entries, which is that they should be - manually updated whenever a change is committed. - -2005-01-04 Diane Murray - - * erc.el (erc-connection-established, erc-login): Update the - mode-line. - (erc-update-mode-line-buffer): If `erc-current-nick' returns nil, - use an empty string for ?n character in format spec. Set - `mode-line-process' to ":connecting" while the connection is being - established. - -2005-01-04 Lawrence Mitchell - - * AUTHORS: Update list of authors. - -2005-01-02 Diane Murray - - * erc-goodies.el (erc-control-characters): New customization - group. - (erc-interpret-controls-p): Small fix, addition to - documentation. Updated customization to allow 'remove as a value. - Use 'erc-control-characters as `:group'. - (erc-interpret-mirc-color): Use 'erc-control-characters as - `:group'. - (erc-beep-p): Updated documentation. Use 'erc-control-characters - as `:group'. - (define-erc-module irccontrols): Add `erc-controls-highlight' to - `erc-insert-modify-hook' and `erc-send-modify-hook' since it - changes the text's appearance. - (erc-controls-remove-regexp, erc-controls-interpret-regexp): New - variables. - (erc-controls-highlight): Fixed so that highlighting works even if - there is no following control character. Fixed mirc color - highlighting; now respecting `erc-interpret-mirc-color'. Fixed a - bug where emacs would get stuck in a loop when \C-g was in a - message and `erc-beep-p' was set to nil (default setting). - -2004-12-29 Francis Litterio - - * erc-goodies.el (erc-interpret-controls-p): Changed docstring to - reflect the new meaning if this is set to 'remove. - (erc-controls-interpret): Rephrased docstring to be more accurate. - (erc-controls-strip): New function that behaves like the - recently-removed erc-strip-controls -- it removes all IRC color - and highlighting control characters. - (erc-controls-highlight): Changed to support the new 'remove value - that variable erc-interpret-controls-p might have. - -2004-12-28 Francis Litterio - - * erc-ibuffer.el, erc-list.el, erc-page.el, erc-speedbar.el: - Changed all calls to erc-interpret-controls (which no longer - exists) to call erc-controls-interpret (the new name of the same - function). - -2004-12-28 Francis Litterio - - * erc-goodies.el (erc-controls-interpret): Added this function to - replace the recently-removed erc-interpret-controls. Also added - a (require 'erc) to solve a byte-compile problem. - -2004-12-28 Francis Litterio - - * erc.el (erc-controls-interpret): Added this function to replace - the recently-removed erc-interpret-controls. - -2004-12-27 Jorgen Schaefer - - * erc-truncate.el (erc-truncate-buffer-to-size): Check for - logging even better (via lawrence). - -2004-12-26 Jorgen Schaefer - - * erc-truncate.el (erc-truncate-buffer-to-size): Much saner - logging detection (via lawrence). - -2004-12-25 Jorgen Schaefer - - * erc-goodies.el (erc-controls-highlight): Treat single C-c - correctly. - -2004-12-24 Jorgen Schaefer - - * erc-goodies.el, erc.el: Deleted IRC control character processing - and implemented a sane version in erc-goodies.el as a module. - - * erc.el (erc-merge-controls, erc-interpret-controls, - erc-decode-controls, erc-strip-controls, erc-make-property-list, - erc-prepend-properties): Removed. - - (erc-interpret-controls-p, erc-interpret-mirc-color, erc-bold-face - erc-inverse-face, erc-underline-face, fg:erc-color-face0, - fg:erc-color-face1, fg:erc-color-face2, fg:erc-color-face3, - fg:erc-color-face4, fg:erc-color-face5, fg:erc-color-face6, - fg:erc-color-face7, fg:erc-color-face8, fg:erc-color-face9, - fg:erc-color-face10, fg:erc-color-face11, fg:erc-color-face2, - fg:erc-color-face13, fg:erc-color-face14, fg:erc-color-face15, - bg:erc-color-face1, bg:erc-color-face2, bg:erc-color-face3, - bg:erc-color-face4, bg:erc-color-face5, bg:erc-color-face6, - bg:erc-color-face7, bg:erc-color-face8, bg:erc-color-face9, - bg:erc-color-face10, bg:erc-color-face11, bg:erc-color-face2, - bg:erc-color-face13, bg:erc-color-face14, bg:erc-color-face15, - erc-get-bg-color-face, erc-get-fg-color-face, - erc-toggle-interpret-controls): Moved. - - * erc-goodies.el (erc-beep-p, irccontrols, erc-controls-highlight, - erc-controls-propertize): New. - -2004-12-24 Jorgen Schaefer - - * erc-goodies.el, erc.el: The Small Extraction of Stuff[tm] commit. - Moved some functions from erc.el to erc-goodies.el, and - transformed them to erc modules in the process. - - imenu autoload stuff moved. I don't know why it is here at all. - - Moved: scroll-to-bottom, make-read-only, distinguish-noncommands, - smiley, unmorse, erc-occur (the last isn't a module, but still - moved) - (erc-input-line-position, erc-add-scroll-to-bottom, - erc-scroll-to-bottom, erc-make-read-only, erc-noncommands-list, - erc-send-distinguish-noncommands, erc-smiley, erc-unmorse, - erc-occur): Moved from erc.el to erc-goodies.el. - (smiley): Module moved from erc.el to erc-goodies.el. - (scrolltobottom, readonly, noncommands, unmorse): New modules. - -2004-12-20 Diane Murray - - * erc.el (erc-format-away-status): Use `a', not `away' - that's - why it's there. - (erc-update-mode-line-buffer): The values of `mode-line-process' - and `mode-line-buffer-identification' are normally lists. - Conform. - -2004-12-18 Jorgen Schaefer - - * erc.el (erc-process-ctcp-query, erc-process-ctcp-reply): Display - message in the active window, not the server window. - -2004-12-16 Theresa O'Connor - - * erc-track.el (erc-track-position-in-mode-line): Check for - 'erc-track-mode variable with boundp. From Adrian Aichner - . - -2004-12-16 Jorgen Schaefer - - * erc.el (erc-upcase-first-word): New function. The old way used - in erc-send-ctcp-message would eat consecutive whitespace etc. - (erc-send-ctcp-message, erc-send-ctcp-notice): Use it. - -2004-12-15 Theresa O'Connor - - * erc.el (erc-send-ctcp-message): Fix braino with my previous - patch. It always helps to C-x C-s before `cvs commit'. - -2004-12-15 Theresa O'Connor - - * erc.el (erc-send-ctcp-message): Only upcase the ctcp command, - and not the entire message. Brian Palmer's change of 2004-12-12 had broken /me. - Shouting is bad! :) - -2004-12-14 Diane Murray - - * erc-nets.el (erc-networks-alist): Change undernet to Undernet as - is used in `erc-server-alist', so that completion works when using - `erc-server-select'. This should fix Debian bug #282003 (erc: - cannot connect to Undernet). - -2004-12-14 Diane Murray - - * erc-backend.el (def-edebug-spec): Only run this if 'edebug is - available. - -2004-12-14 Diane Murray - - * erc.el: The last change to `erc-mode-line-format' introduced a - bug in XEmacs - it can't handle the #(" "...) strings at all. The - following changes fix the bug and simplify the mode-line handling - considerably. (erc-mode-line-format): Now defined as a string - which will be formatted using `format-spec' and take the place of - `mode-line-buffer-identification' in the mode line. - (erc-header-line-format): Now defined as a string to be formatted - using `format-spec'. - (erc-prepare-mode-line-format): Removed. - (erc-format-target, erc-format-target-and/or-server, - erc-format-away-status, erc-format-channel-modes): New functions. - Basically the old `erc-prepare-mode-line-format' split apart. - (erc-update-mode-line-buffer): Set - `mode-line-buffer-identification' to the formatted - `erc-mode-line-format', set `mode-line-process' to ": CLOSED" if - the connection has been terminated, and set `header-line-format' - (if it is bound) to the formatted `erc-header-line-format', then - do a `force-mode-line-update'. - -2004-12-12 Diane Murray - - * erc.el (erc-modules): Disable modules removed with `customize'. - (erc-update-modules): Try to give a more descriptive error - message. - -2004-12-12 Diane Murray - - * erc-complete.el, erc.el, erc-list.el, erc-nets.el, - * erc-nicklist.el, erc-pcomplete.el, erc-replace.el, erc-speak.el, - * erc-truncate.el (erc-buffers, erc-coding-systems, erc-display, - erc-mode-line-and-header, erc-ignore, erc-query, - erc-quit-and-part, erc-paranoia, erc-scripts, erc-old-complete, - erc-list, erc-networks, erc-nicklist, erc-pcomplete, erc-replace, - erc-truncate): New customization groups. - (erc-join-buffer, erc-frame-alist, erc-frame-dedicated-flag, - erc-reuse-buffers): Use 'erc-buffers as `:group'. - (erc-default-coding-system, erc-encoding-coding-alist): - Use 'erc-coding-systems as `:group'. - (erc-hide-prompt, erc-show-my-nick, erc-prompt, - erc-input-line-position, erc-command-indicator, erc-notice-prefix, - erc-notice-highlight-type, erc-interpret-controls-p, - erc-interpret-mirc-color, erc-minibuffer-notice, - erc-format-nick-function): Use 'erc-display as `:group'. - (erc-mode-line-format, erc-header-line-format, - erc-header-line-uses-help-echo-p, erc-common-server-suffixes, - erc-mode-line-away-status-format): Use 'erc-mode-line-and-header - as `:group'. - (erc-hide-list, erc-ignore-list, erc-ignore-reply-list, - erc-minibuffer-ignored): Use 'erc-ignore as `:group'. - (erc-auto-query, erc-query-on-unjoined-chan-privmsg, - erc-format-query-as-channel-p): Use 'erc-query as `:group'. - (erc-kill-buffer-on-part, erc-kill-queries-on-quit, - erc-kill-server-buffer-on-quit, erc-quit-reason-various-alist, - erc-part-reason-various-alist, erc-quit-reason, erc-part-reason): - Use 'erc-quit-and-part as `:group'. - (erc-verbose-server-ping, erc-paranoid, erc-disable-ctcp-replies, - erc-anonymous-login, erc-show-channel-key-p): Use 'erc-paranoia as - `:group'. - (erc-startup-file-list, erc-script-path, erc-script-echo): Use - 'erc-scripts as `:group'. - (erc-nick-completion, erc-nick-completion-ignore-case, - erc-nick-completion-postfix): Use 'erc-old-complete as `:group'. - (erc-chanlist-progress-message, erc-no-list-networks, - erc-chanlist-frame-parameters, erc-chanlist-hide-modeline, - erc-chanlist-mode-hook): Use 'erc-list as `:group'. - (erc-server-alist, erc-networks-alist): Use 'erc-networks as - `:group'. - (erc-settings): Use `defvar' instead of `defcustom' since this is - only a draft which doesn't work. - (erc-nicklist-window-size): Use 'erc-nicklist as `:group'. - (erc-pcomplete-nick-postfix, - erc-pcomplete-order-nickname-completions): Use 'erc-pcomplete as - `:group'. - (erc-replace-alist): Use 'erc-replace as `:group'. - (erc-speak-filter-timestamp): Use 'erc-speak as `:group'. - (erc-max-buffer-size): Use 'erc-truncate as `:group'. - -2004-12-12 Jorgen Schaefer - - * erc.el (erc-scroll-to-bottom): Go to the end of the buffer - before recentering. This allows editing multiple lines more - conveniently in CVS Emacs. This also undos a change by antifuchs - who said this goto-char would mess up redisplay. Extensive testing - couldn't reproduce that problem. - -2004-12-12 Brian Palmer - - * erc.el (erc-send-ctcp-message): upcase the ctcp message (so that - version becomes VERSION, for example). - (erc-iswitchb): Make the argument optional in non-interactive - invocation, so erc-iswitchb can be substituted directly for - iswitchb in code. - -2004-12-11 Diane Murray - - * erc-track.el (erc-track-position-in-mode-line): Allow for the - fact that `erc-track-mode' isn't bound when file is loaded. - -2004-12-11 Diane Murray - - * erc-track.el (erc-track-position-in-mode-line): New customizable - variable. (erc-track-remove-from-mode-line): New function. - Remove `erc-modified-channels-string' from the mode-line. - (erc-track-add-to-mode-line): New function. Add - `erc-modified-channels-string' to the mode-line using the value of - `erc-track-position-in-mode-line' to determine whether to add it - to the beginning or the end of `mode-line-modes' (only available - with GNU Emacs versions above 21.3) or to the end of - `global-mode-string'. - (erc-track-mode, erc-track-when-inactive-mode): Use the new - functions. - -2004-12-11 Jorgen Schaefer - - * erc.el (erc-cmd-BANLIST): Use (buffer-name) and not - (erc-default-target) for the buffer name - buffer names are case - sensitive. - -2004-12-11 Brian Palmer - - * erc.el (erc-message-type): Added the message "MODE" to the known - erc-message-type widget, so that (for example) people can tell - erc-track-exclude-types to ignore mode changes. The others tag - also needed to be made an inline list, so that it's merged with - the given constants, instead of being inserted as a list. - -2004-12-10 Jorgen Schaefer - - * erc-track.el, erc.el: Update to get ERC look nicely in CVS Emacs. - - * erc.el (erc-mode-line-format): When on CVS emacs, use the new - format. - - * erc-track.el (track module): When on CVS emacs, modify - mode-line-modes instead of global-mode-string. The latter is way - to far too the right. - -2004-11-18 Mario Lang - - * Makefile, debian/changelog: debian release 20041118-1 - -2004-11-03 Diane Murray - - * erc-button.el (erc-button-buttonize-nicks): Set default value to - `t'. Updated documentation and customization `:type' to reflect - usage. - -2004-10-29 Johan Bockgård - - * AUTHORS: Added self. - -2004-10-17 Diane Murray - - * erc-list.el: Added local variables for this file. - (erc-list-version): New. - (erc-cmd-LIST): Take &rest rather than &optional arguments, as was - done in revision 1.21. Allow for input when called interactively. - (erc-prettify-channel-list, erc-chanlist-toggle-sort-state): Use - `unless' instead of when not. - -2004-10-17 Diane Murray - - * erc-backend.el (erc-handle-unknown-server-response): Fixed so - that the contents are only shown once. - (MOTD): Display lines in the server buffer if it's the first MOTD - sent upon connection. This is to avoid the problem of having the - MOTD of one server showing up in another server's buffer if it took - a while to get connected. - (004): Fixed to show the user modes and channel modes correctly. - (303): Now displays the nicknames returned by ISON instead of the - user's nickname. - (367, 368): Moved up into 300's section of the code. Added - documentation. Use `multiple-value-bind' to set variables in 367. - (391): Fixed so that the server name is shown correctly. - -2004-10-17 Diane Murray - - * erc.el (erc-process-sentinel): Use CPROC instead of - `erc-process' in debug message. Should fix a bug where an error - saying "Buffer *scratch* has no process" would occur when - disconnected. - (erc-cmd-SV): Check for X toolkit after checking for more specific - features. (erc--kill-server): Set `quitting' to non-nil so that - we don't automatically reconnect. - -2004-10-05 Jorgen Schaefer - - * erc.el (erc-ignored-user-p): Don't require regexes to match the - beginning. - -2004-09-11 Jorgen Schaefer - - * erc.el: group erc: Moved to 'applications (patch by bojohan) - -2004-09-08 Jorgen Schaefer - - * erc-button.el (erc-button-remove-old-buttons): Remove 'keymap - not 'local-map. - -2004-09-03 Jorgen Schaefer - - * erc-backend.el: JOIN response handler: Typo fix of the last - commit. - -2004-09-03 Jorgen Schaefer - - * erc-backend.el: JOIN response handler: Run `erc-join-hook' - without arguments as specified in the docstring. - -2004-08-27 Jorgen Schaefer - - * erc.el (erc-send-current-line): Removed unused variable SENTP. - -2004-08-19 Jorgen Schaefer - - * erc.el: ERC-SEND-COMPLETED-HOOK used to be run when the prompt - was already displayed. We restore this behavior (thanks to bojohan - and TerryP for noticing). We also fix the docstring of - ERC-SEND-COMPLETED-HOOK, since the hook is (and used to be) called - even if nothing was sent to the server. - (erc-send-completed-hook): Fixed docstring. - (erc-send-current-line): Add incantation for - erc-send-completed-hook. - (erc-send-input): Remove incantation for erc-send-completed-hook. - -2004-08-18 Jorgen Schaefer - - * erc-backend.el: response-handler 368: Use s368, not s367. - -2004-08-17 Jorgen Schaefer - - * erc.el (erc-scroll-to-bottom): Don't scroll when we're not - connected anymore. - -2004-08-17 Jorgen Schaefer - - * erc-backend.el, erc.el: Handle /mode #emacs b output without - errors and such. First, handle unknown format specs gracefully - (that is, give a useful error). Then, provide handlers for the - banlist replies. - - * erc-backend.el: New handler for 367 and 368. Removed from default - handler. - - * erc.el: Provide english catalog for s367 and s368. - (erc-format-message): Give an error message when we don't find an - entry. - -2004-08-17 Jorgen Schaefer - - * erc-fill.el: erc-fill-variable could be confused about really - long nicks. We put an upper limit on the length of the fill prefix. - (erc-fill-variable): Adjust fill-prefix. - erc-fill-variable-maximum-indentation: New variable. - -2004-08-17 Francis Litterio - - * erc.el (erc-send-input): Fixed a bug where this function - referenced variable "input" instead of variable "str". - -2004-08-16 Francis Litterio - - * erc-list.el (erc-chanlist-highlight-line): Fixed a bug where - this function failed to set the correct face for highlighting the - current line. - -2004-08-14 Jorgen Schaefer - - * erc-fill.el (erc-fill-variable): Don't fuck up when the - looking-at didn't work. - -2004-08-14 Jorgen Schaefer - - * erc.el (erc-send-single-line): Call the hooks to change the - appearance for something only if we actually inserted something, - doh. - (erc-display-command): Display the prompt outside of the area that - set the text properties on. - -2004-08-14 Jorgen Schaefer - - * erc.el: Refactored erc-send-current-line. This should fix some - dormant bugs, and make the whole thing actually readable. Yay. - Some changes in behavior were made. Whitespace at the end of lines - sent is not removed anymore, but that shouldn't bother anyone. - Additionally, errors in commands or hooks shouldn't prevent the - prompt from showing up again now. - (erc-parse-current-line): Removed. - (erc-send-current-line): Refactored. - (erc-send-input): New function. - (erc-send-single-line): New function. - (erc-display-command): New function. - (erc-display-msg): New function. - (erc-user-input): New function. - -2004-08-13 Jorgen Schaefer - - * erc.el (erc-cmd-SERVER): Use newer keyword call interface to - erc-select, and handle the error if it can't resolve the host. - -2004-08-11 Jorgen Schaefer - - * erc-backend.el, erc.el: erc-backend.el (404 response handler): - New function. We now support "cannot send to channel". - - * erc.el (erc-define-catalog call): Added s404. - (erc-ctcp-ECHO-reply, erc-ctcp-CLIENTINFO-reply, - erc-ctcp-FINGER-reply, erc-ctcp-PING-reply, erc-ctcp-TIME-reply, - erc-ctcp-VERSION-reply): Display reply in the active window, not - the server window. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-with-all-buffers-of-server): Actually make it left - to right, doh. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-with-all-buffers-of-server): Evaluate left-to-right - so we don't surprise a user. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-process-input-line): Parentophobia! Another - paren-fix. - -2004-08-10 Jorgen Schaefer - - * erc-backend.el: PRIVMSG NOTICE response handler: Killed one paren - too much. Poor paren. Got resurrected. - -2004-08-10 Jorgen Schaefer - - * erc-track.el: Make server buffers showing up in the mode line - optional. Thanks to Daniel Knapp on the EmacsWiki for this patch. - - erc-track-exclude-server-buffer: New variable. - (erc-track-modified-channels): Return a server buffer only if - erc-track-exclude-server-buffer is nil. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-cmd-DESCRIBE): Don't parse arguments. - -2004-08-10 Jorgen Schaefer - - * erc-truncate.el (erc-truncate-buffer-to-size): Use - erc-insert-marker, not (point-max), to decide the length of the - buffer. A long input line shouldn't make the buffer smaller. - -2004-08-10 Jorgen Schaefer - - * erc-macs.el, erc-members.el: The change to hashes for channel - members has been made some time ago. Clean up the various tries to - do this in the past. - - * erc-macs.el, erc-members.el: Removed. - -2004-08-10 Jorgen Schaefer - - * erc-backend.el, erc-ibuffer.el, erc-members.el, erc.el: Nothing - big changed here. Really. Uhm, maybe the info-buffers are gone or - so. Can't really remember. Don't worry, nothing important is - missing. - - erc-speedbar.el looks nice btw, did you know? - - Adjusted various places in erc.el, erc-backend.el, erc-ibuffer.el - and erc-members.el - too numerous to list here, sorry. - - * erc.el: erc-use-info-buffers: Removed. erc-info-mode-map: - Removed. - (erc-info-mode): Removed. - (erc-find-channel-info-buffer): Removed. - (erc-update-channel-info-buffer): Removed. - (erc-update-channel-info-buffers): Removed. - - * erc-members.el: erc-update-member renamed to - erc-update-channel-member for better clarity. - -2004-08-10 Jorgen Schaefer - - * erc.el: This change improves the help output on a bogus command - invocation. We display the command as it would be typed by the - user, not as it is seen by Emacs. - - (erc-get-arglist): Is now called erc-function-arglist, and returns - now an arglist without the enclosing parens. - (erc-command-name): New function. - (erc-process-input-line): Pass the command name, not the function - name. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-process-input-line): Fix bug when the command - doesn't have an arglist or no documentation. Thanks bojohan again - :) - -2004-08-10 Jorgen Schaefer - - * erc-match.el (erc-add-entry-to-list), - (erc-remove-entry-from-list): Update docstring, a TEST argument is - not given. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-with-buffer): Really fix this docstring. - -2004-08-10 Jorgen Schaefer - - * erc.el (erc-with-buffer): Fix double evaluation in macro, and - fix docstring. - -2004-08-10 Brian Palmer - - * erc.el (erc-cmd-JOIN): Use erc-member-ignore-case instead of - member-ignore-case. - -2004-08-09 Johan Bockgård - - * erc-backend.el: Define an "Edebug specification" for the - `define-erc-response-handler' macro. This means that one can step - through response handlers defined by this macro with edebug. Maybe - more macros would benefit from this? - -2004-08-09 Johan Bockgård - - * erc-pcomplete.el (pcomplete/erc-mode/CTCP): New function. - Completion for the /CTCP command. (erc-pcomplete-ctcp-commands): - New variable. List of ctcp commands. - -2004-08-09 Johan Bockgård - - * erc-list.el: Clean up docstrings. - (erc-prettify-channel-list): Extend properties to cover the entire - line, including the newline, to make it look - better. - (erc-chanlist-highlight-line): Ditto. - (erc-chanlist-mode-hook): Make it a defcustom. - -2004-08-09 Jorgen Schaefer - - * erc.el (erc-compute-full-name): Typo fix, should be full-name, - not name. - -2004-08-09 Jorgen Schaefer - - * erc.el (erc): Setup the buffer to be shown in a window at the - end of this function. This enables 'window-noselect to work - properly. - (erc, erc-send-current-line): Fix some - goto-char/open-line/goto-char to goto-char/insert. - -2004-08-08 Jorgen Schaefer - - * erc.el (erc-parse-user): Live with bogus info from bouncers. - -2004-07-31 Brian Palmer - - * erc.el (erc-select): Change the docstring to reflect the new - arguments; include the arguments in the docstring for non-cvs - emacs. Change the parameters to call erc-compute-* instead of - using the erc-* variables directly. - (erc-compute-server): Made argument optional. - (erc-compute-nick): ditto. - (erc-compute-full-name): ditto. (erc-compute-port): ditto. - -2004-07-30 Francis Litterio - - * erc.el (erc-cmd-BANLIST): Fixed a bug where channel-banlist was - not reset to nil before fetching an updated banlist from the - server. - -2004-07-30 Francis Litterio - - * erc.el (erc-cmd-BANLIST): Fixed a bug where the - 'received-from-server property on variable channel-banlist was not - being reset to nil. This fixes the symptom where one types - /BANLIST and sees "No bans for channel: #whatever" when you know - there are bans. - -2004-07-23 Brian Palmer - - * erc.el (erc-select-read-args): Use erc-compute-nick to - calculate the default nickname - -2004-07-20 Brian Palmer - - * erc.el (erc-process-sentinel-1): New function. This is an - auxiliary function refactored out of erc-process-sentinel to - decide a server buffer's fate (whether it should be killed, and - whether erc should attempt to auto-reconnect). Michael Olson - helped with this. - (erc-kill-server-buffer-on-quit): New variable. Used in - erc-process-sentinel-1 to decide whether to kill a server buffer - when the user quit normally. - (erc-process-sentinel): Auxiliary function erc-process-sentinel-1 - split out. The function body has `with-current-buffer' wrapped - around it, to ensure separation of messages if multiple - connections were being made. Use `if' instead of `cond' in places - where the decision is binary. The last (useless, since the server - connection is closed) prompt in the server buffer is removed. - Color "erc terminated" and "erc finished" messages with - erc-error-face. Mark the buffer unmodified so that, if not killed - automatically, the user is not prompted to save it. - -2004-07-16 Brian Palmer - - * erc.el (erc-select-read-args): New function. Prompts the user - for arguments to pass to erc-select and erc-select-ssl. - (erc-select): Use (erc-select-read-args) when called interactively - to get its arguments. When non-interactively, use keyword - arguments. - (erc-select-ssl): Ditto. - (erc-compute-port): New function. Parallel to erc-compute-server, - but comes up with a default value for an IRC server's port. - -2004-07-16 Jorgen Schaefer - - * erc-match.el (erc-match-message): Quote the current nickname. - -2004-07-12 Brian Palmer - - * erc-list.el (erc-chanlist-mode): Remove explicit invocation of - erc-chanlist-mode-hook, since it's automatically invoked by - define-derived-mode - -2004-07-03 Jorgen Schaefer - - * erc-match.el (erc-match-current-nick-p): Quote current nick for - regexp parsing. - -2004-06-27 Johan Bockgård - - * erc-nickserv.el (erc-nickserv-identify-mode): Fix erroneous - parentheses in call to `completing-read'. - -2004-06-23 Alex Schroeder - - * Makefile (release): Depend on autoloads, and copy erc-auto.el - into the tarball. - -2004-06-14 Francis Litterio - - * erc.el (erc-log-irc-protocol): Fixed minor bug where each line - received from a server was logged as two lines (one with text and - one blank). - -2004-06-08 Brian Palmer - - * erc-list.el (erc-chanlist-frame-parameters): Made customizable. - (erc-chanlist-header-face): Changed to use defface with some - reasonable defaults instead of make-face, and removed the - associated -face variable. - (erc-chanlist-odd-line-face): Ditto. - (erc-chanlist-even-line-face): Ditto. - (erc-chanlist-highlight-face): New variable. Holds a face used for - highlighting the current line. - (erc-cmd-LIST): Use erc-member-ignore-case instead of - member-ignore-case. - (erc-chanlist-post-command-hook): Change to move the highlight - overlay instead of refontifying the entire buffer. - (erc-chanlist-dehighlight-line): Added to detach the highlight - overlay from the buffer. - -2004-05-31 Jorgen Schaefer - - * erc.el: erc-mode-line-format: Add column numbers. - -2004-05-31 Adrian Aichner - - * erc-autojoin.el: Typo fix. - - * erc-dcc.el (erc-dcc-do-GET-command): Use expand-file-name. - (erc-dcc-get-file): XEmacs set-buffer-multibyte compatibility. - - * erc-log.el: Append `erc-log-setup-logging' to - `erc-connect-pre-hook' so that `erc-initialize-log-marker' is run - first (markers are needed by `erc-log-setup-logging'). - (erc-enable-logging): Docstring fix. - (erc-log-setup-logging): Move `erc-log-insert-log-on-open' to (1- - (point-max)) when doing `erc-log-insert-log-on-open'. Modified - version of a patch by Lawrence Mitchell. - (erc-log-all-but-server-buffers): Do `save-excursion' as well. - (erc-current-logfile): Pass buffer name as target - argument to `erc-generate-log-file-name-function' if - `erc-default-target' is nil. - (erc-generate-log-file-name-with-date): Use expand-file-name. - (erc-generate-log-file-name-short): Ditto. - (erc-save-buffer-in-logs): Do `save-excursion' and test whether - erc-last-saved-position is a marker. - - * erc-members.el: Avoid miscompiling macro `erc-log' and - `with-erc-channel-buffer' by requiring 'erc at compile time. - - * erc-sound.el: Use expand-file-name. - - * erc.el (erc-debug-log-file): Ditto. - (erc-find-file): Ditto. - -2004-05-26 Francis Litterio - - * erc.el, erc-backend.el (erc-cmd-BANLIST): Added a missing "'" - that was preventing /BANLIST from working. In erc-backend.el, - added server response handler for 367 and 368 responses to get - /BANLIST working. - -2004-05-26 Francis Litterio - - * erc.el: Removed an eval-when-compile that was preventing the - byte-compiled version of this file from loading. - -2004-05-26 Francis Litterio - - * erc.el: Undid part of my last change. I suspect it was wrong. - -2004-05-26 Francis Litterio - - * erc.el: Silenced several byte-compiler warnings. - -2004-05-26 Francis Litterio - - * erc.el (erc-log-irc-protocol): Fixed problem where this function - misformatted IRC protocol text if multiple lines were received from - the server at one time. - -2004-05-25 Francis Litterio - - * erc.el (erc-toggle-debug-irc-protocol): Cosmetic changes to the - informational text in the *erc-protocol* buffer. - -2004-05-24 Francis Litterio - - * erc.el (erc-log-irc-protocol, erc-process-filter): Now the lines - inserted in the *erc-protocol* buffer are prefixed with the name - of the network to/from which the data is going/coming. This makes - reading the *erc-protocol* buffer much easier when connected to - multiple networks. - -2004-05-23 Jeremy Bertram Maitin-Shepard - - * erc-backend.el: Fixes server message parsing so that command - arguments specified after the colon are not treated specially. All - arguments are added to the `command-args' field, and the - `contents' points to the last element in the `command-args' list. - This allows ERC to connect to networks such as Undernet. Although - keeping `contents' allows many of the response handlers to - continue to work as-is, many other are probably broken by this - patch. - -2004-05-20 Lawrence Mitchell - - * HACKING: Add comment that C-c C-a can be useful if you write - ChangeLog entries using Emacs' standard functions. - -2004-05-17 Diane Murray - - * erc-speedbar.el: Ignore errors when attempting to require dframe - (there are a couple implementations of speedbar, one of which uses - of dframe). - (erc-speedbar-version): New. - (erc-speedbar-goto-buffer): Use dframe functions if dframe is - available. - -2004-05-17 Diane Murray - - * erc-autojoin.el: Added local variables for this file. - (erc-autojoin-add): The channel name is in `erc-response.contents'. - -2004-05-17 Mario Lang - - * erc-log.el: Don't autoload a define-key statement, erc-mode-map - might not be known yet - -2004-05-16 Lawrence Mitchell - - * erc-backend.el (erc-parse-server-response): Revert to original - `erc-parse-line-from-server' version, since new version breaks for - a number of edge cases. - -2004-05-14 Diane Murray - - * erc-backend.el (erc-handle-unknown-server-response): New - function. Added to `erc-default-server-functions'. Display - unknown responses to the user. - (221): Don't show nickname in modes list. - (254): Fixed to use 's254. - (303): Added docstring. - (315, 318, 323, 369): Ignored responses grouped together. - (391): New. - (406, 432): Use ?n, not ?c in `erc-display-message'. - (431, 445, 446, 451, 462, 463, 464, 465, 481, 483, 485, 491, 501, - 502): All error responses with no arguments grouped together. - -2004-05-14 Diane Murray - - * erc.el (erc-message-type-member): Use `erc-response.command'. - `erc-track-exclude-types' should be respected again. - (erc-cmd-TIME): Fixed to work with and without server given as - argument. - (erc-define-catalog): Added, s391, s431, s445, s446, s451, s462, - s463, s464, s465, s483, s484, s485, s491, s501, s502. - -2004-05-14 Lawrence Mitchell - - * HACKING: Typo fix. - -2004-05-14 Lawrence Mitchell - - * Makefile (erc-auto.el): Pass -f flag to rm so that we don't fail - if erc-auto.elc doesn't exist. - -2004-05-14 Lawrence Mitchell - - * erc-backend.el (erc-with-buffer): Autoload. - (erc-parse-server-response): XEmacs' `replace-match' only replaces - subexpressions when operating on buffers, not strings, work around - it. - (461): Command with invalid arguments is `second', not `third'. - -2004-05-14 Diane Murray - - * erc-notify.el (erc-notify-NICK): Use `erc-response.contents' to - get nickname. - -2004-05-13 Lawrence Mitchell - - * erc-track.el: Indentation fixes. - (track-when-inactive): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc-notify.el (notify): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - (erc-notify-timer, erc-notify-JOIN, erc-notify-NICK) - (erc-notify-QUIT): Use new accessors for PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-nickserv.el (services, erc-nickserv-identify-mode): Use - `erc-server-FOO-functions', not `erc-server-FOO-hook. - (erc-nickserv-identify-autodetect): Use new accessors for PARSED - argument. - -2004-05-13 Lawrence Mitchell - - * erc-netsplit.el (netsplit): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - (erc-netsplit-JOIN, erc-netsplit-MODE, erc-netsplit-QUIT): Use new - accessors for PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-nets.el: Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc-menu.el (erc-menu-definition): Only allow listing of - channels if `erc-cmd-LIST' is fboundp. - -2004-05-13 Lawrence Mitchell - - * erc-match.el: Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - (erc-get-parsed-vector-nick, erc-get-parsed-vector-type): Use new - accessors for PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-list.el (erc-chanlist, erc-chanlist-322): Use new accessors - for PARSED argument. Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc-ezbounce.el (erc-ezb-notice-autodetect): Use new accessors - for PARSED argument. - (erc-ezb-initialize): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc-dcc.el: Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - (erc-dcc-no-such-nick): Use new accessors for PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-bbdb.el (erc-bbdb-whois, erc-bbdb-JOIN, erc-bbdb-NICK): Use - new accessors for PARSED argument. - (BBDB): Use `erc-server-FOO-functions', not `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc-autojoin.el (autojoin): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - (erc-autojoin-add, erc-autojoin-remove): Use new accessors for - PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-autoaway.el (autoaway): Use `erc-server-FOO-functions', not - `erc-server-FOO-hook. - -2004-05-13 Lawrence Mitchell - - * erc.el (erc-backend): Require. - (erc-disconnected-hook, erc-join-hook, erc-quit-hook) - (erc-part-hook, erc-kick-hook): Docstring fix, we now use - `erc-server-FOO-functions', rather than `erc-server-FOO-hook'. - (erc-event-to-hook-name, erc-event-to-hook): Remove. - (erc-once-with-server-event) - (erc-once-with-server-event-global): Use `erc-get-hook' - (erc-process-filter): Use `erc-parse-server-response'. - (erc-cmd-IDLE, erc-cmd-BANLIST, erc-cmd-MASSUNBAN): New accessors - for PARSED argument. Rename all `erc-server-FOO-hook' to - `erc-server-FOO-functions'. - (erc-server-364-hook, erc-server-365-hook, erc-server-367-hook) - (erc-server-368-hook, erc-server-KILL-hook) - (erc-server-PONG-hook, erc-server-200-hook, erc-server-201-hook) - (erc-server-202-hook, erc-server-203-hook, erc-server-204-hook) - (erc-server-205-hook, erc-server-206-hook, erc-server-208-hook) - (erc-server-209-hook, erc-server-211-hook, erc-server-212-hook) - (erc-server-213-hook, erc-server-214-hook, erc-server-215-hook) - (erc-server-216-hook, erc-server-217-hook, erc-server-218-hook) - (erc-server-219-hook, erc-server-241-hook, erc-server-242-hook) - (erc-server-243-hook, erc-server-244-hook, erc-server-249-hook) - (erc-server-261-hook, erc-server-262-hook, erc-server-302-hook) - (erc-server-323-hook, erc-server-342-hook, erc-server-351-hook) - (erc-server-381-hook, erc-server-382-hook, erc-server-391-hook) - (erc-server-392-hook, erc-server-393-hook, erc-server-394-hook) - (erc-server-395-hook, erc-server-402-hook, erc-server-404-hook) - (erc-server-407-hook, erc-server-409-hook, erc-server-411-hook) - (erc-server-413-hook, erc-server-414-hook, erc-server-415-hook) - (erc-server-422-hook, erc-server-423-hook, erc-server-424-hook) - (erc-server-431-hook, erc-server-436-hook, erc-server-437-hook) - (erc-server-441-hook, erc-server-443-hook, erc-server-444-hook) - (erc-server-445-hook, erc-server-446-hook, erc-server-451-hook) - (erc-server-462-hook, erc-server-463-hook, erc-server-464-hook) - (erc-server-465-hook, erc-server-467-hook, erc-server-471-hook) - (erc-server-472-hook, erc-server-473-hook, erc-server-483-hook) - (erc-server-491-hook, erc-server-502-hook): Remove. - (erc-call-hooks, erc-parse-line-from-server): Remove - (erc-server-hook-list): Remove. Remove top-level call too. - (erc-server-ERROR, erc-server-INVITE, erc-server-JOIN) - (erc-server-KICK, erc-server-MODE, erc-server-NICK) - (erc-server-PART, erc-server-PING, erc-server-PONG) - (erc-server-PRIVMSG-or-NOTICE, erc-server-QUIT) - (erc-server-TOPIC, erc-server-WALLOPS, erc-server-001) - (erc-server-004, erc-server-005, erc-server-221, erc-server-252) - (erc-server-253, erc-server-254, erc-server-301, erc-server-303) - (erc-server-305, erc-server-306, erc-server-311-or-314) - (erc-server-312, erc-server-313, erc-server-317, erc-server-319) - (erc-server-320, erc-server-321, erc-server-322, erc-server-324) - (erc-server-329, erc-server-330, erc-server-331, erc-server-332) - (erc-server-333, erc-server-341, erc-server-352, erc-server-353) - (erc-server-366, erc-server-MOTD, erc-server-379) - (erc-server-401, erc-server-403, erc-server-405, erc-server-406) - (erc-server-412, erc-server-421, erc-server-432, erc-server-433) - (erc-server-437, erc-server-442, erc-server-461, erc-server-474) - (erc-server-475, erc-server-477, erc-server-481, erc-server-482) - (erc-server-501): Move to erc-backend.el - (erc-auto-query, erc-banlist-store, erc-banlist-finished) - (erc-banlist-update, erc-connection-established) - (erc-process-ctcp-query, erc-display-server-message): Use new - accessors for PARSED argument. - -2004-05-13 Lawrence Mitchell - - * erc-backend.el (erc-parse-server-response) - (erc-handle-parsed-server-response, erc-get-hook) - (define-erc-response-handler): New functions. - (erc-response): New struct for server responses. - (erc-server-responses): New variable. - (erc-call-hooks): Move from erc.el and rework. - (ERROR, INVITE, JOIN, KICK, MODE, NICK, PART, PING, PONG) - (PRIVMSG, NOTICE, QUIT, TOPIC, WALLOPS, 001, MOTD, 376, 004) - (252, 253, 254, 250, 301, 303, 305, 306, 311, 312, 313, 315) - (317, 318, 319, 320, 321, 322, 324, 329, 330, 331, 332, 333) - (341, 352, 353, 366, 369, 379, 401, 403, 405, 406, 412, 421) - (432, 433, 437, 442, 461, 474, 477, 481, 482, 501, 323, 221) - (002, 003, 371, 372, 374, 375, 422, 251, 255, 256, 257, 258) - (259, 265, 266, 377, 378, 314, 475, 364, 365, 367, 368, 381) - (382, 391, 392, 393, 394, 395, 200, 201, 202, 203, 204, 205) - (206, 208, 209, 211, 212, 213, 214, 215, 216, 217, 218, 219) - (241, 242, 243, 244, 249, 261, 262, 302, 342, 351, 402, 404) - (407, 409, 411, 413, 414, 415, 423, 424, 431, 436, 441, 443) - (444, 445, 446, 451, 462, 463, 464, 465, 467, 471, 472, 473) - (483, 491, 502, 005, KILL): Move from erc.el and rework using - `define-erc-response-handler' and erc-response struct. - -2004-05-12 Diane Murray - - * erc.el: A few bug fixes to avoid errors after disconnect, - including the "Selecting deleted buffer" bug. - (erc-channel-user-op-p, erc-channel-user-voice-p): Make sure NICK - is non-nil (`erc-current-nick' can return nil). - (erc-server-buffer): Make sure the buffer isn't a #. - (erc-server-buffer-live-p): New function. - (erc-display-line, erc-join-channel, erc-prepare-mode-line-format, - erc-away-p): Use `erc-server-buffer-live-p' to make sure process - buffer exists. - (erc-send-current-line): If there is no server buffer, let the - user know. - -2004-05-12 Diane Murray - - * erc.el, erc-log.el: C-c C-l keybinding now defined in - erc-log.el. - (erc-log-version): New. - (erc-cmd-JOIN): Fix applied for bug where /join -invite causes - errors when there's no `invitation'. - -2004-05-11 Diane Murray - - * erc.el (erc-cmd-JOIN): Make sure `chnl' is non-nil before trying - to join anything (chnl is not set if /join -invite is used but - there's no `invitation'). - -2004-05-10 Diane Murray - - * erc-log.el: Define C-c C-l keybinding outside of `erc-log-mode', - making it available all the time; autoload definition. - (erc-log-version): New. - -2004-05-09 Diane Murray - - * AUTHORS, CREDITS, Makefile, erc-autoaway.el, erc-autojoin.el, - erc-button.el, erc-chess.el, erc-dcc.el, erc-ezbounce.el, - erc-fill.el, erc-ibuffer.el, erc-imenu.el, erc-lang.el, - erc-list.el, erc-log.el, erc-macs.el, erc-match.el, erc-members.el, - erc-menu.el, erc-nets.el, erc-netsplit.el, erc-nickserv.el, - erc-notify.el, erc-page.el, erc-ring.el, erc-speak.el, - erc-speedbar.el, erc-stamp.el, erc-track.el, erc-truncate.el, - erc-xdcc.el, erc.el: Applied all relevant bug fixes and code - cleanup made between the time of the ERC_4_0_RELEASE tag until now. - -2004-05-09 Diane Murray - - * erc-menu.el: Updated copyright years. - -2004-05-09 Lawrence Mitchell - - * erc.el (erc-update-channel-info-buffer): Correct bug in sorting - of channel users. Tiny change from Andreas Schwab - . - -2004-05-09 Lawrence Mitchell - - * erc-fill.el (erc-fill-variable): Fix docstring. - -2004-05-09 Lawrence Mitchell - - * erc-button.el (erc-button-add-button): Use 'keymap - text-property, rather than 'local-map, since it's cross-emacs - compatible. Pass :mouse-down-action into `widget-convert-button' - as 'erc-button-click-button, to make XEmacs happy. Replace bogus - reference to erc-widget-press-button with erc-button-press-button. - (erc-button-click-button): New (ignored) first argument, to make - XEmacs behave when pressing buttons. - (erc-button-press-button): New (ignored) &rest argument. - -2004-05-09 Adrian Aichner - - * erc-log.el (erc-conditional-save-buffer): Fix docstring - reference to erc-save-queries-on-quit. - (erc-conditional-save-queries): Ditto. - -2004-05-06 Diane Murray - - * erc-speedbar.el: Updated copyright years. Added local variables - for this file; fixed indenting. - (erc-speedbar): New group. - (erc-speedbar-sort-users-type): New variable. - (erc-speedbar-buttons): Handle query buffers (fixes a bug where an - error would be thrown if the current buffer was a query). Ignore - unknown buffers. - (erc-speedbar-expand-channel): Show limit and key with channel - modes. Sort users according to `erc-speedbar-sort-users-type'. - (erc-speedbar-insert-user): Fixed bug where only nicks with more - info were being listed, and those were shown twice. - (erc-speedbar-goto-buffer): Don't use dframe functions, as dframe - isn't available with the default speedbar. - -2004-05-06 Diane Murray - - * erc.el (erc-sort-channel-users-alphabetically): New function. - (erc-server-412, erc-server-432, erc-server-475): New functions. - (erc-server-412-hook, erc-server-432-hook, erc-server-475-hook): - Use them. - (erc-server-401, erc-server-403, erc-server-405) - (erc-server-421, erc-server-474, erc-server-481): Use catalog - messages. - (erc-define-catalog): Added s401, s403, s405, s412, s421, s432, - s474, s475, and s481. - -2004-05-06 Diane Murray - - * erc-nickserv.el: Added documentation to Commentary, Usage. - Removed `outline-mode' from file local variables. - (erc-services-mode): Use `erc-nickserv-identify-mode' to add - hooks. - (erc-nickserv-identify-mode): New function. - (erc-nickserv-identify-mode): New variable. - (erc-prompt-for-nickserv-password, erc-nickserv-passwords): - Changed docstring. - (erc-nickserv-identify-autodetect): Use - `erc-nickserv-call-identify-function'. Docstring change. - (erc-nickserv-identify-on-connect, - erc-nickserv-identify-on-nick-change, - erc-nickserv-call-identify-function): New functions. - (erc-nickserv-identify): PASSWORD is not optional. Autoload - function. - -2004-05-05 Diane Murray - - * erc.el (erc-join-hook, erc-quit-hook, erc-part-hook, - erc-kick-hook, erc-connect-pre-hook): Now customizable. - (erc-nick-changed-functions): New hook. - (erc-server-NICK): Run `erc-nick-changed-functions' with the - arguments NEW-NICK and OLD-NICK. - (erc-channel-user-voice-p, erc-channel-user-voice-p): Shortened - docstring. - -2004-05-05 Lawrence Mitchell - - * HACKING: New section on function/variable naming and coding - conventions. - -2004-05-05 Lawrence Mitchell - - * erc.el (erc-wash-quit-reason): Quote regexp special characters - in NICK, LOGIN and HOST. - -2004-05-04 Diane Murray - - * erc.el (erc-server-parameters): Typo fix in docstring. - (erc-input-line-position): `:type' is now a choice between integer - and nil. (erc-mode-map): Bind `erc-get-channel-mode-from-keypress' - to C-c C-o instead of C-c RET (C-c C-m). (erc-cmd-GQUIT): Use - REASON as argument when calling `erc-cmd-QUIT'. - -2004-05-03 Lawrence Mitchell - - * erc-nicklist.el: Initial version. - -2004-04-28 Diane Murray - - * erc-menu.el: Added local variables for file, fixed indenting. - (erc-menu-version): New variable. - (erc-menu-definition): "List channels": New. "Join channel": Use - `erc-connected' as test. "Start a query": New. "List channel - operators": New. "Input action": Moved up. "Set topic": Fixed - test so it's only active in channels. "Leave this channel": Moved - down. "Track hidden channel buffers": Removed. "Enable/Disable - ERC Modules": New. - -2004-04-28 Diane Murray - - * erc.el (erc-mode-map): Removed binding for - `erc-save-buffer-in-logs' (moved to erc-log.el). - (erc-cmd-QUERY, erc-cmd-OPS): Now interactive. - -2004-04-28 Diane Murray - - * erc-log.el: Added local variables for this file. - (erc-log-channels-directory): Added directory as a choice in - `:type'. - (define-erc-module): Define and undefine key binding (C-c - C-l) for `erc-save-buffer-in-logs' here. - -2004-04-28 Diane Murray - - * erc-nets.el: Added local variables for this file. - (erc-networks-alist): Fixed `:type' to work better in - customization. - -2004-04-28 Diane Murray - - * erc-match.el: Added local variables for file. (erc-keywords): - Use `list' instead of `cons' in `:type'. Fixes bug where mismatch - was shown in customization. (erc-current-nick-highlight-type): - Escape parentheses in docstring. Added keyword, nick-or-keyword as - options in `:type'. - -2004-04-28 Diane Murray - - * erc-stamp.el: Added local variables for file. - (erc-away-timestamp-format): Allow nil as a choice in `:type'. - (erc-timestamp-intangible): Changed `:type' to boolean. - (erc-timestamp-right-column): Added `:group' and `:type'. - -2004-04-28 Diane Murray - - * erc.el (erc-modules): Added bbdb, log, match, sound, and stamp - as `:type' options; changed documentation for autojoin, fill, - pcomplete, track. (erc-prompt-for-channel-key): New variable. - (erc-join-channel): Only prompt for key if - `erc-prompt-for-channel-key' is non-nil. (erc-format-my-nick): New - function. (erc-send-message, erc-send-current-line): Use it. - -2004-04-24 Johan Bockgård - - * erc-track.el (erc-track-modified-channels): Fix indentation. - -2004-04-24 Johan Bockgård - - * erc-match.el (erc-hide-fools): Docstring fix. - (erc-log-matches-types-alist): Added `current-nick' to valid - choices. - -2004-04-20 Diane Murray - - * erc-page.el, erc-ezbounce.el, erc-speak.el, erc-match.el, - erc-track.el (erc-ezbounce, erc-page, erc-speak): Groups defined. - (erc-match, erc-track): `erc' is parent group. - (erc-ezb-regexp, erc-ezb-login-alist): Added `:group'. - -2004-04-20 Jorgen Schaefer - - * erc-fill.el: Fixed erc-fill-static so it breaks the lines at the - right column and respects timestamps. Patch by Simon Siegler - - (erc-fill-static): Major rewrite and split up into some functions. - (erc-count-lines): Removed. - (erc-fill-regarding-timestamp): New function. - (erc-timestamp-offset): New function. - (erc-restore-text-properties): New function. - (erc-fill-variable): Respect leftbound timestamp. This is still - broken if someone has both erc-timestamp-only-if-changed-flag set - and erc-insert-timestamp-function set to - 'erc-insert-timestamp-left, but otherwise it works now. - -2004-04-20 Diane Murray - - * erc.el (erc-cmd-SV): Show features gtk, mac-carbon, multi-tty. - Fixed so that arguments fit the format (build date was not being - shown). - -2004-04-19 Lawrence Mitchell - - * erc.el (erc-update-channel-topic): Error if `channel-topic' is - unbound. Remove %-sign substitution. - (erc-update-mode-line-buffer): Escape %-signs in `channel-topic' - here. - -2004-04-19 Diane Murray - - * erc.el (erc-send-action, erc-ctcp-query-ACTION, - erc-ctcp-reply-ECHO-hook): Let `erc-display-message-highlight' - propertize the message. - (erc-display-message-highlight): Allow for any erc-TYPE-face. - (erc-cmd-JOIN): Display error message instead of throwing an error - if there's no `invitation'. - (erc-cmd-PART): Allow for no reason if channel is provided. Fixes - bug where user would part the current channel with the other - channel's name as reason when no reason was given. - (erc-server-vectors, erc-debug-missing-hooks): Added docstring. - (erc-server-JOIN): Moved `erc-join-hook' to JOIN-you section. - `erc-join-hook' called by `run-hook-with-args', sending the ARGS - `chnl' and the channel's buffer. Changed an instance of if - without else to when. - (erc-server-477): New function. - (erc-server-477-hook): Use `erc-server-477'. - (erc-define-catalog): Added `no-invitation'. - -2004-04-14 Diane Murray - - * erc-nickserv.el: Local variables for file added. - (erc-nickserv-passwords): Customization: Network symbols updated - to reflect `erc-nickserv-alist'. Allow user to type in network - symbol. - (erc-nickserv-alist): Now customizable variable. - -2004-04-09 Diane Murray - - * erc-autoaway.el (erc-autoaway-reset-idletime): Make sure `line' - is a string to avoid errors upon startup. - -2004-04-06 Diane Murray - - * erc-autoaway.el (erc-autoaway-version): New variable. - (erc-auto-discard-away): Updated docstring. - (erc-autoaway-no-auto-back-regexp): New variable. - (erc-autoaway-reset-idletime): Use it. Hopefully a better solution - which allows for aliases to "/away" and any other text that the - user wants to ignore when `erc-auto-discard-away' is non-nil. - -2004-04-06 Diane Murray - - * erc-autoaway.el (erc-autoaway-reset-idletime): Forgot /gaway in - regexp. - -2004-04-06 Diane Murray - - * erc-autoaway.el (erc-autoaway-reset-idletime): If the user sends - an "/away" command, don't call `erc-autoaway-set-back', fixes bug - where ERC would send "/away" when user was already away and sent an - "/away reason". Changed `l' to `line' for better understanding. - (erc-autoaway-set-back): Changed `l' to `line' for better - understanding. - -2004-04-05 Diane Murray - - * erc.el (erc-set-channel-key): Now able to remove key. - (erc-set-channel-limit): Now able to remove limit. - (erc-get-channel-mode-from-keypress): Fixed docstring. - -2004-04-04 Diane Murray - - * erc.el (erc-join-channel): Allow for optional channel key. - (erc-set-modes): Need to set `channel-key' to nil in case of mode - changes during split. - (erc-show-channel-key-p): New variable. - (erc-prepare-mode-line-format): Only show key if - `erc-show-channel-key-p' is non-nil. - -2004-04-04 Diane Murray - - * erc.el (channel-key): New variable. - (erc-update-channel-key): New function. - (erc-set-modes, erc-parse-modes, erc-update-modes, erc, - erc-update-channel-info-buffer): Deal with channel keys. - (erc-prepare-mode-line-format): Show channel key in header-line. - (erc-server-NICK): Show nick change in server buffer as well. - (erc, erc-send-command, erc-banlist-store, erc-banlist-update, - erc-load-irc-script-lines, - erc-arrange-session-in-multiple-windows, erc-handle-login, - erc-find-channel-info-buffer): Changed when not to unless. - (erc-server-MODE): Changed if without else to when. - -2004-03-27 Adrian Aichner - - * erc.el (erc-cmd-BANLIST): Use `truncate-string-to-width' - instead of `truncate-string' alias. - (erc-nickname-in-use): Ditto. - -2004-03-27 Francis Litterio - - * erc-list.el (erc-cmd-list): Fixed error caused by erc-cmd-LIST - passing a non-sequence to erc-chanlist. - -2004-03-22 Jeremy Bertram Maitin-Shepard - - * erc.el: Add new hook `erc-join-hook', which is run when we join a - channel. - -2004-03-22 Jeremy Bertram Maitin-Shepard - - * erc.el: Replaced existing notice user notification system and - the configuration options, which consisted of - `erc-echo-notices-in-minibuffer-flag' and - `erc-echo-notices-in-current-buffer' with two new hooks, - `erc-echo-notice-hook' and `erc-echo-notice-always-hook'. - - When user notification is needed, `erc-echo-notice-always-hook' is - first run using `run-hook-with-args', then `erc-echo-notice-hook' - is run using `run-hook-with-args-until-success'. - - In addition to these hooks, a large number of functions, which are - described in the documentation strings of those hooks, were added - which can be used to achieve a large variety of different - behaviors. - - The current default behavior, which is identical to the existing - default behavior, is for `erc-echo-notice-always-hook' to be set to - `(erc-echo-notice-in-default-buffer). - -2004-03-21 Diane Murray - - * erc-track.el (erc-modified-channels-display): Added a space - before opening bracket. - -2004-03-21 Diane Murray - - * erc.el (erc-format-query-as-channel-p): New variable. - (erc-server-PRIVMSG-or-NOTICE): If `erc-format-query-as-channel-p' - is nil, messages in the query buffer are formatted like private - messages. - - (erc-server-252-hook, erc-server-253-hook, erc-server-254-hook, - erc-server-256-hook, erc-server-257-hook, erc-server-258-hook, - erc-server-259-hook, erc-server-371-hook, erc-server-372-hook, - erc-server-374-hook, erc-server-374-hook, erc-server-442-hook, - erc-server-477-hook): Removed, now defined in - `erc-server-hook-list'. - (erc-display-server-message): New function. - (erc-server-252, erc-server-253, erc-server-254, erc-server-442): - New functions. - (erc-server-hook-list): Added 250, 256, 257, 258, 259, 265, 266, - 377, 378, 477 - using `erc-display-server-message'. 251, 255 now - use `erc-display-server-message'. Added 252, 253, 254, 442 - - using respective erc-server-* functions. 371, 372, 374, 375 now - defined here. - (erc-define-catalog): Added s252, s253, s254, s442. - (erc-server-001, erc-server-004, erc-server-005): Fixed - documentation. - -2004-03-20 Diane Murray - - * erc-stamp.el: Commentary: Changed `erc-stamp-mode' to - `erc-timestamp-mode'. - (erc-insert-timestamp-left): Use `erc-timestamp-face' on filler - spaces as well. - -2004-03-19 Diane Murray - - * erc.el (erc-send-action): Use `erc-input-face'. - (erc-display-message-highlight): If the requested highlighting - type doesn't match, just display the string with no highlighting - and warn about it with `erc-log'. - (erc-cmd-JOIN): If user is already on the requested channel, - switch to that channel's buffer. - (erc-ctcp-query-ACTION): Use `erc-action-face' for nick as well. - (erc-header-line-use-help-echo-p): New variable. - (erc-update-mode-line-buffer): Use `help-echo' for header-line if - `erc-header-line-use-help-echo-p' is non-nil. - -2004-03-18 Adrian Aichner - - * erc-nets.el: Use two arguments version of `make-obsolete', if - third argument is not supported (for XEmacs). - -2004-03-18 Andreas Fuchs - - * CREDITS: added CREDITS entry for Adrian Aichner - -2004-03-18 Andreas Fuchs - - * erc-xdcc.el, erc.el, erc-autoaway.el, erc-autojoin.el, - erc-button.el, erc-dcc.el, erc-ezbounce.el, erc-imenu.el, - erc-list.el, erc-log.el, erc-match.el, erc-members.el, - erc-menu.el, erc-netsplit.el, erc-notify.el, erc-speedbar.el, - erc-stamp.el, erc-track.el, erc-truncate.el: - (erc-coding-sytem-for-target): Removed. - (erc-coding-system-for-target): New. - (erc-autoaway-use-emacs-idle): Typo fix. - (erc-auto-set-away): Ditto. - (erc-auto-discard-away): Ditto. - (autojoin): Ditto. - (erc-button-alist): Ditto. - (erc-dcc-auto-masks): Ditto. - (erc-dcc-chat-send-input-line): Ditto. - (erc-ezb-get-login): Ditto. - (erc-unfill-notice): Ditto. - (erc-save-buffer-in-logs): Ditto. - (match): Ditto. - (erc-log-matches-types-alist): Ditto. - (erc-match-directed-at-fool-p): Ditto. - (erc-match-message): Ditto. - (erc-update-member): Ditto. - (erc-ignored-reply-p): Ditto. - (erc-menu-definition): Ditto. - (erc-netsplit-QUIT): Ditto. - (erc-notify-list): Ditto. - (erc-speedbar-update-channel): Ditto. - (erc-speedbar-item-info): Ditto. - (erc-stamp): Ditto. - (erc-timestamp-intangible): Ditto. - (erc-add-timestamp): Ditto. - (erc-timestamp-only-if-changed-flag): Ditto. - (erc-show-timestamps): Ditto. - (erc-track-priority-faces-only): Ditto. - (erc-modified-channels-alist): Ditto. - (erc-unique-substrings): Ditto. - (erc-find-parsed-property): Ditto. - (erc-track-switch-direction): Ditto. - (erc-truncate-buffer-to-size): Ditto. - (erc-xdcc): Ditto. - (erc-auto-reconnect): Ditto. - (erc-startup-file-list): Ditto. - (erc-once-with-server-event): Ditto. - (erc-once-with-server-event-global): Ditto. - (erc-mode): Ditto. - (erc-generate-new-buffer-name): Ditto. - (erc): Ditto. - (erc-open-ssl-stream): Ditto. - (erc-default-coding-system): Ditto. - (erc-encode-string-for-target): Ditto. - (erc-decode-string-from-target): Ditto. - (erc-scroll-to-bottom): Ditto. - (erc-decode-controls): Ditto. - (erc-channel-members-changed-hook): Ditto. - (erc-put-text-property): Ditto. - (erc-add-default-channel): Ditto. - -2004-03-17 Diane Murray - - * erc.el (erc-process-sentinel): Cancel ping timer upon - disconnect. - (erc-cmd-PART): Use same regexp as `erc-cmd-QUIT' when no #channel - is provided. - (erc-nick-uniquifier, erc-manual-set-nick-on-bad-nick-p): `:group' - was missing, added. - (erc-part-reason-zippy, erc-part-reason-zippy): Removed FIXME - comments. I see no problem allowing typed in reasons. - -2004-03-16 Diane Murray - - * erc-stamp.el (erc-insert-timestamp-left): Added support for - `erc-timestamp-only-if-changed-flag' and added docstring. - (erc-timestamp-only-if-changed-flag): Updated documentation. - -2004-03-13 Francis Litterio - - * erc-nets.el (erc-network-name): No longer marked as obsolete. - Why was this function made obsolete? There is no other function - that performs this task. Some of us use these functions in our - personal ERC configs. - -2004-03-12 Lawrence Mitchell - - * erc.el (erc-buffer-filter): Use `with-current-buffer'. - (erc-process-input-line): Append newline to documentation. Fixes a - bug whereby the prompt would be put on the same line as the output. - (erc-cmd-GQUIT): Only try and send QUIT if the process is alive. - -2004-03-12 Lawrence Mitchell - - * erc-log.el: Only add top-level hooks if `erc-enable-logging' is - non-nil. - -2004-03-10 Damien Elmes - - * erc-nets.el: From Adrian Aichner (adrian /at/ xemacs /dot/ org) - * erc-nets.el: XEmacs make-obsolete only takes two arguments. - -2004-03-10 Diane Murray - - * erc-nets.el (erc-determine-network): Use `erc-session-server' if - `erc-announced-server' is nil to avoid error if server does not - send 004 (RPL_MYINFO) message. - -2004-03-10 Lawrence Mitchell - - * erc-nets.el (erc-server-alistm erc-settings): Use lowercase - "freenode", as in `erc-networks-alist'. - -2004-03-10 Lawrence Mitchell - - * erc-nickserv.el (erc-nickserv-alist): Use lowercase "freenode", - as in `erc-networks-alist'. - -2004-03-10 Lawrence Mitchell - - * erc-dcc.el (pcomplete/erc-mode/DCC): Append "send" as a list. - -2004-03-10 Francis Litterio - - * erc-nets.el (erc-networks-alist): Changed "Freenode" to - "freenode". - -2004-03-10 Francis Litterio - - * erc-list.el (erc-cmd-LIST): Improved the docstring. Made - message to user more accurate depending on whether a single - channel is being listed or not. - -2004-03-10 Lawrence Mitchell - - * erc-nets.el (erc-determine-network): Make matching logic simpler - (suggested by Damian Elmes). - (erc-current-network, erc-network-name): Add `make-obsolete' form. - (erc-set-network-name): Indentation fix. - (erc-ports-list): Add docstring. Rework function body to use - `nconc'. - -2004-03-09 Diane Murray - - * erc-list.el, erc-notify.el (require 'erc-nets): Added. - -2004-03-08 Diane Murray - - * erc.el (erc-network-name): Function definition moved to - erc-nets.el. The functions `erc-determine-network' and - `erc-network' in erc-nets.el do what this did before. Deprecated. - Use (erc-network) instead. - -2004-03-08 Diane Murray - - * erc-nickserv.el: Changed copyright notice. Now require - erc-nets. erc-nets.el now takes care of network-related functions - and variables. - (erc-nickserv-alist): Changed network symbols to match those in - `erc-networks-alist' in erc-nets.el. - (erc-nickserv-identify-autodetect): Use `erc-network'. - (erc-nickserv-identify): Use `erc-network'. Changed wording for - interactive use, now shows current nick. - (erc-networks): Removed. Use `erc-networks-alist' as defined in - erc-nets.el. - (erc-current-network): Function definition moved to erc-nets.el. - The functions `erc-determine-network' and `erc-network' in - erc-nets.el do what this did before. Deprecated. Use - (erc-network) instead. - -2004-03-08 Diane Murray - - * erc-nets.el: Added commentary, `erc-nets-version'. - (erc-server-alist): Changed Brasnet to BRASnet. - (erc-networks-alist): All networks (except EFnet and IRCnet) now - have a MATCHER. (erc-network): New variable. - (erc-determine-network): New function. Determine the network the - user is on. Use the server parameter NETWORK, if provided, else - parse the server name and search for a match (regexp and loop by - wencem) in `erc-networks-alist'. Return the name of the network - or "Unknown" as a symbol. - (erc-network): New function. Returns value of `erc-network'. Use - this when the current buffer is not the server process buffer. - (erc-current-network): Returns the value of `erc-network' as - expected by users who used the function as it was defined in - erc-nickserv.el. Deprecated. - (erc-network-name): Returns the value of `erc-network' as expected - by users who used the function as it was defined in erc.el. - Deprecated. - (erc-set-network-name): New function. Added to - `erc-server-375-hook' and `erc-server-422-hook'. - (erc-unset-network-name): New function. Added to - `erc-disconnected-hook'. - (erc-server-select): Small documentation word change. - -2004-03-07 Diane Murray - - * AUTHORS, CREDITS: disumu info updated - -2004-03-06 Lawrence Mitchell - - * erc-list.el (erc-cmd-LIST): Take &rest rather than &optional - arguments. - (erc-chanlist): Construct correct LIST command from list of - channels. - -2004-03-06 Lawrence Mitchell - - * erc.el (erc-update-mode-line-buffer): Add 'help-echo property to - header-line text. This allows header lines longer than the width - of the current window to be seen. - -2004-03-06 Jorgen Schaefer - - * erc-match.el (erc-match-directed-at-fool-p): Also check for - "FOOL, " - -2004-03-06 Jorgen Schaefer - - * erc-match.el (erc-match-message): Only use nick-or-keyword if - we're matching our nick. - -2004-03-06 Jorgen Schaefer - - * erc-match.el: The highlight type for the current nickname can - now also be 'nick-or-keyword, to highlight the nick of the sender - if that is available, but fall back to highlighting your nickname - in the whole message otherwise. - (erc-current-nick-highlight-type): Adapted docstring accordingly. - (erc-match-message): Added new condition. Also added some comments - to this monster of a function. - -2004-03-06 Jorgen Schaefer - - * erc.el (erc-is-valid-nick-p): Don't check for length less or - equal to 9. - -2004-03-06 Damien Elmes - - * erc-nickserv.el (erc-current-network): the last change resulted - in this function failing when a network identifies itself as - anything other than var.netname.com, so for instance - 'vic.au.austnet.org' fails. This version is only a marginal - improvement over the original, but if we want to be more flexible - we'll probably have to do the iteration ourselves instead of using - assoc. - -2004-03-05 Diane Murray - - * erc.el: Added erc-server-001 which runs when the server sends - its welcome message. It sets the current-nick to reflect the - server's settings. This fixes a bug where nicks that were too long - and got truncated by the server were still set to the old value. - (nickname-in-use): If user wants to try again manually, let user - know that the nick is taken. If not, go through erc-default-nicks - until none are left, and then try one last time with - erc-nick-uniquifier. If it's still a bad-nick, make the user - change nick manually. When applying uniquifier, use NICKLEN if - it's in the server parameters, otherwise use what RFC 2812 says is - the max nick length (9 chars). Added custom variable - erc-manual-set-nick-on-bad-nick-p, which is set to nil and - erc-nick-change-attempt-count. Reset erc-default-nicks and - erc-nick-change-attempt-count when the nick has been changed - successfully. This fixes the bug where ERC would get caught in a - neverending loop of trying to set the same nick if the nick was - too long and the uniquified nick was not available. - - * added erc-cmd-WHOAMI - - * added custom variable erc-mode-line-away-status-format, use this - instead of the previous hard-coded setting - - * erc-server-315|318|369-hook defvar lines removed - they're - already defined in erc-server-hook-list - -2004-03-04 Lawrence Mitchell - - * HACKING: Initial commit. Some thoughts on coding standards. - -2004-03-03 Diane Murray - - * erc-track.el: added the variable erc-track-priority-faces-only - which adds the option to ignore changes in a channel unless there - are faces from the erc-track-faces-priority-list in the message - options are nil, 'all, or a list of channel name strings - -2004-03-01 Diane Murray - - * erc.el, erc-ibuffer.el, erc-menu.el: Changed erc-is-channel-op - and erc-is-channel-voice to erc-channel-user-op-p and - erc-channel-user-voice-p to better match erc-channel-user - structure (and emacs lisp usage) - -2004-03-01 Diane Murray - - * erc.el, erc-ibuffer.el, erc-menu.el: - erc-track-modified-channels-mode is now erc-track-mode - -2004-02-29 Diane Murray - - * erc-match.el: Added 'keyword option to - erc-current-nick-highlight-type highlights all instances of - current-nick in the message ('nickname option in cvs revisions 1.9 - - 1.11 had same effect) - -2004-02-28 Jorgen Schaefer - - * erc-button.el: Add Lisp: prefix for the EmacsWiki Elisp area. - (erc-button-alist): Added Lisp: prefix. - (erc-emacswiki-lisp-url): New variable. - (erc-browse-emacswiki-lisp): New function. - -2004-02-27 Lawrence Mitchell - - * erc.el (erc-get-arglist): Use `substitute-command-keys', rather - than hard-coding C-h f for `describe-function'. - -2004-02-26 Johan Bockgård - - * erc-log.el (erc-save-buffer-in-logs): bind `inhibit-read-only' - to t around call to `erase-buffer'. - -2004-02-23 Theresa O'Connor - - * erc-chess.el, erc-dcc.el, erc-ezbounce.el, erc-list.el, - erc-macs.el, erc-ring.el, erc-stamp.el, erc.el: Normalized buffer - local variable creation. - -2004-02-17 Lawrence Mitchell - - * erc.el (erc-scroll-to-bottom, erc-add-scroll-to-bottom): Mention - `erc-input-line-position' in docstring. - -2004-02-13 Jorgen Schaefer - - * erc.el (erc-kick-hook): Typo fix. - -2004-02-13 Jeremy Bertram Maitin-Shepard - - * erc.el: Added `erc-kick-hook', which is called when the local - user is kicked from a channel. Fixed a bug in `erc-cmd-OPS', such - that the command now works. Added `erc-remove-channel-users', in - order to fix a number of significant bugs relating to channel - parting. - -2004-02-12 Jorgen Schaefer - - * erc.el (erc-display-prompt): Remove last change. This caused a - lot of trouble :( - -2004-02-12 Jorgen Schaefer - - * erc.el (erc-display-prompt): Also set 'field property, so C-j - works on an empty prompt. - -2004-02-12 Lawrence Mitchell - - * erc.el (erc-update-channel-topic): Ensure that `channel-topic' - does not contain any bare format controls. - -2004-02-10 Jorgen Schaefer - - * erc-stamp.el (erc-timestamp-intangible): New variable (user - feature request) - (erc-format-timestamp): Use erc-timestamp-intangible. - -2004-02-07 Jeremy Bertram Maitin-Shepard - - * erc-button.el: Fixed bug related to nickname buttonizing and text - fields due to erc-stamp. - -2004-02-07 Jeremy Bertram Maitin-Shepard - - * CREDITS: Added mention of my change of ERC to use hash tables. - -2004-02-07 Jeremy Bertram Maitin-Shepard - - * AUTHORS: Added myself to the list. - -2004-02-05 Lawrence Mitchell - - * erc.el: From Jeremy Maitin-Shepard : - (erc-remove-channel-user): Use `delq' not `delete'. - (erc-get-buffer): Pass PROC through to `erc-buffer-filter'. - (erc-process-sentinel): Use `erc' rather than `erc-reconnect' for - auto-reconnection. - -2004-02-02 Lawrence Mitchell - - * erc.el (erc-buffer-list-with-nick): Apply `erc-downcase' NICK. - -2004-01-30 Alex Schroeder - - * erc.el (erc-get-buffer): Use erc-buffer-filter. - -2004-01-30 Johan Bockgård - - * erc.el: From jbms: - (erc-get-channel-nickname-list): New function. - (erc-get-server-nickname-list): New function. - (erc-get-server-nickname-alist): New function. - (erc-get-channel-nickname-alist): New function. - -2004-01-30 Johan Bockgård - - * erc-match.el (erc-add-entry-to-list, - erc-remove-entry-from-list): Use `erc-member-ignore-case' to - compare entries. - (erc-add-pal, erc-add-fool): Fix type bug. Use - `erc-get-server-nickname-alist'. - -2004-01-29 Johan Bockgård - - * erc.el: From jbms: Adds xemacs compatibility to hash table - channel-members patch. - -2004-01-29 Johan Bockgård - - * erc.el (erc-update-undo-list): Rewritten. Update - buffer-undo-list in place. Deal with XEmacsesque - entries (extents) in the list. - (erc-channel-users): Fix unescaped open-paren in left column in - docstring. - -2004-01-29 Johan Bockgård - - * erc-ring.el (erc-replace-current-command): Exclude the prompt - from the deleted region and don't redisplay the prompt (because - `erc-display-prompt' flushes `buffer-undo-list'). - -2004-01-29 Johan Bockgård - - * erc-match.el (erc-add-entry-to-list): Use `symbol-value' instead - of `eval'. - -2004-01-28 Jorgen Schaefer - - * erc.el (erc-kill-buffer-function): maphash was missing an - argument. - -2004-01-28 Jorgen Schaefer - - * Makefile, erc-autoaway.el, erc-button.el, erc-ibuffer.el, - erc-lang.el, erc-list.el, erc-match.el, erc-menu.el, erc-page.el, - erc-pcomplete.el, erc-speedbar.el, erc.el: HUGE change by jbms. - This makes channel-members a hash, erc-channel-users. - - Modified files: Makefile erc-autoaway.el erc-button.el - erc-ibuffer.el erc-lang.el erc-list.el erc-match.el erc-menu.el - erc-page.el erc-pcomplete.el erc-speedbar.el erc.el - - The changes are too numerous to document properly. Have fun with - the breakage. - -2004-01-27 Jorgen Schaefer - - * erc.el (erc-send-input-line): Add a space to empty lines so the - server likes them. - -2004-01-25 Jorgen Schaefer - - * erc.el: erc-send-whitespace-lines: New variable. - (erc-send-current-line): Use erc-send-whitespace-lines. Also, - removed superfluous test for empty line in the mapc, since the - blank line test should find all. I do like to be able to send an - empty line when i want to! - (erc-send-current-line): Check for point being in input line - before checking for blank lines. - -2004-01-21 Lawrence Mitchell - - * erc.el (erc-display-line-1): Move `erc-update-undo-list' outside - `save-restriction'. Removing need for temporary variable. - (erc-send-current-line): Fix bug introduced by last change, remove - complement in blank line regexp. - -2004-01-20 Lawrence Mitchell - - * erc.el (erc-update-undo-list): Add logic to catch the case when - `buffer-undo-list' is t, indentation cleanup. - (erc-send-current-line): Reverse logic for matching blank lines. - -2004-01-20 Lawrence Mitchell - - * erc.el (erc-input-line-position): New variable. If non-nil, - specifies the argument to `recenter' in `erc-scroll-to-bottom'. - (erc-scroll-to-bottom): Use it. - -2004-01-20 Lawrence Mitchell - - * erc.el: From Johan Bockgård : - (erc-update-undo-list): New function. Update `buffer-undo-list' - so that calling `undo' in an ERC buffer doesn't mess up the - existing text. - (erc-display-line-1): Use it. - -2004-01-19 Lawrence Mitchell - - * erc.el (erc-beg-of-input-line): Use `forward-line' rather than - `beginning-of-line'. Docstring fix. - (erc-end-of-input-line): Docstring fix. - -2004-01-13 Jorgen Schaefer - - * erc.el (erc-display-prompt): Remove the undo list after - displaying the prompt, so the user can't undo ERC changes, which - breaks some stuff anyways. This way the user can still undo his - editing, but not ours. - -2004-01-12 Jorgen Schaefer - - * erc.el (erc-scroll-to-bottom): Should recenter on the bottom - line, not the second-to-last one. - -2004-01-12 Lawrence Mitchell - - * erc.el (erc-bol): Fix bug introduced in my changes from 2004-01-11. - -2004-01-12 Lawrence Mitchell - - * erc.el: From Brian Palmer - (erc-cmd-JOIN): Use `erc-member-ignore-case', rather than - `member-ignore-case'. - -2004-01-12 Jorgen Schaefer - - * erc.el: There was an inconsistency where the values of op and - voice in channel-names could be 'on or 'off after an update, t and - nil before. The intended version was to have t or nil, so i fixed - it to do so. - (channel-names): Updated docstring. - (erc-update-current-channel-member): Clarified docstring, fixed so - it sets t or nil on an update as well, not only on an add. - (erc-cmd-OPS): Updated not to check for 'on (the only function that - did this!) - -2004-01-12 Lawrence Mitchell - - * erc.el (erc-part-reason-various-alist, - erc-update-mode-line-buffer): Fix docstring - -2004-01-11 Lawrence Mitchell - - * erc.el (erc-update-mode-line): Fix typo. - -2004-01-11 Lawrence Mitchell - - * erc.el (erc-prompt-interactive-input): Removed. - (erc-display-prompt): Removed `erc-prompt-interactive-input' - option. (erc-interactive-input-map): Removed. - - Major docstring fixes. - -2004-01-07 Francis Litterio - - * erc.el (erc-cmd-OPS): Added this function. - (erc-cmd-IDLE): Switched from using erc-display-message-highlight - to erc-make-notice. - -2004-01-07 Francis Litterio - - * erc-list.el (erc-cmd-LIST): Switched from using - erc-display-message-highlight to erc-make-notice. - -2004-01-07 Francis Litterio - - * erc.el (erc-once-with-server-event): Added a sentence to the - docstring. Now returns the uninterned symbol that is added to the - server hook. - (erc-cmd-IDLE): Changed to use erc-once-with-server-event instead - of erc-once-with-server-event-global. - -2004-01-06 Francis Litterio - - * erc-list.el (erc-chanlist-hide-modeline): New variable. - (erc-chanlist): Now displays message as a notice. Also hides the - modeline if erc-chanlist-hide-modeline is non-nil. - -2004-01-05 Francis Litterio - - * erc.el (erc-server-PRIVMSG-or-NOTICE): Now nicks appear as - in query buffers, instead of as *nick*. - -2004-01-03 Francis Litterio - - * erc.el (erc-once-with-server-event-global): Changed to return - the uninterned symbol that it creates. - (erc-cmd-LIST): Changed to clean up hooks that don't run. - -2004-01-03 Francis Litterio - - * erc-pcomplete.el (pcomplete/erc-mode/IDLE): Added to support new - /IDLE command. - -2004-01-03 Francis Litterio - - * erc.el (erc-once-with-server-event-global): New function. Like - erc-once-with-server-event, except it modifies the global value of - the event hook. - (erc-cmd-IDLE): New function. Implements the new /IDLE command. - Usage: /IDLE NICK (erc-seconds-to-string): New function. Converts - a number of seconds to an English phrase. - -2004-01-02 Francis Litterio - - * erc-list.el: Added variable erc-chanlist-mode-hook. - -2003-12-30 Francis Litterio - - * erc.el(erc-cmd-HELP): - Changed to prefer giving help for erc-cmd-* functions over - similarly-named Elisp functions (e.g., erc-cmd-LIST vs. list). - -2003-12-28 Francis Litterio - - * erc.el(erc-query-buffer-p): Added this function. - -2003-12-28 Jorgen Schaefer - - * erc.el(erc-cmd-SV): Use erc-emacs-build-time. - - * erc-compat.el: erc-emacs-build-time: New variable. - - * erc.el(erc-cmd-SAY): - Reintroduced the feature where the spaces between - "/SAY" and the rest of the line were being sent with the message. - -2003-12-28 Francis Litterio - - * erc.el(erc-server-buffer-p): - Fixed a bug where this function sometimes would return - nil when it should return t. - -2003-12-27 Francis Litterio - - * erc.el(erc-generate-new-buffer-name): - Really fixed a bug where ERC would reuse - a connected server buffer when erc-reuse-buffers is non-nil. - (erc-cmd-JOIN): Now we tell the user when he attempts to join the same - channel twice on the same server. - - * erc.el(erc-generate-new-buffer-name): - Fixed a bug where ERC would reuse a connected server buffer when erc-reuse-buffers is non-nil. - - * erc.el(erc-cmd-SAY): - Fixed a bug where the spaces between "/SAY" and the rest of the - line were being sent with the message. - - * erc-list.el: Fixed another typo. - - * erc-list.el: Fixed a typo. - - * erc-list.el: - Added text to the top of the channel list buffer describing the keybinding for - function erc-chanlist-join-channel. - - * erc-list.el: Minor appearance changes. No functional change. - - * erc-list.el: - Implemented function erc-chanlist-join-channel. Added variable - erc-chanlist-channel-line-regexp. Got rid of function - erc-chanlist-pre-command-hook. Changed the logic for how channel lines are - highlighted. - -2003-12-26 Francis Litterio - - * erc-list.el: - Removed a bunch of unused code. No semantic change. - - * erc-list.el: Added lots of functionality. - -2003-12-15 Mario Lang - - * erc-track.el, erc.el: - New custom type erc-message-type, use it in erc-hide-list and erc-track-exclude-types - -2003-12-14 Alex Schroeder - - * erc-track.el(track-when-inactive): New module. - (erc-track-visibility): New option. - (erc-buffer-activity): New variable. - (erc-buffer-activity-timeout): New variable. - (erc-user-is-active): New function. - (erc-buffer-visible): New function. - (erc-modified-channels-update): Replace get-buffer-window call - with call to erc-buffer-visible. - (erc-track-modified-channels): Ditto. - -2003-12-14 Lawrence Mitchell - - * erc-track.el(erc-modified-channels-update): - Force update of modeline. Makes sure - that the tracked channels disappear in other buffers too. - -2003-12-06 Lawrence Mitchell - - * erc.el(define-erc-module): - New optional argument LOCAL-P. If non-nil, then - mode will be created as buffer-local rather than a global mode. - (erc-cmd-CTCP): Fix indentation from last commit. - - * erc-compat.el(erc-define-minor-mode): - Deal with :global and :group keywords. - - * erc-nickserv.el(erc-current-network): - Make server regex more permissive. - - * erc.el(erc-cmd-CTCP): - Don't add a space to end of command when ARGS are - empty. This fixes a bug whereby requests of the form "VERSION " were - being sent, and ignored. - -2003-11-27 Lawrence Mitchell - - * erc-log.el: From Adrian Aichner - * erc-log.el (erc-log-file-coding-system): Use 'binary - coding-system under XEmacs (instead of 'emacs-mule). - * erc-log.el (erc-w32-invalid-file-characters): Removed as no - longer needed. - * erc-log.el (erc-generate-log-file-name-long): Use - `convert-standard-filename', which exists in XEmacs too. - -2003-11-16 Mario Lang - - * erc-identd.el: Code provided by johnw, thanks! - -2003-11-09 Lawrence Mitchell - - * erc.el(erc-latest-version): Clean up docstring. - Remove requirement for w3, wrap REQUIRE statement in IGNORE-ERRORS. - Update viewcvs url to correct location. - (erc-ediff-latest-version): Make sure that we find the uncompiled - erc.el, error if not. - -2003-11-07 Mario Lang - - * erc.el: Add more info to /sv - -2003-11-06 Francis Litterio - - * erc.el: Added optional argument BUFFER to erc-server-buffer-p. - -2003-11-04 Mario Lang - - * AUTHORS: Add sachac - -2003-11-02 Lawrence Mitchell - - * erc.el(erc-server-366): - chnl is 4th element of parsed, not fifth. - (erc-channel-end-receiving-names): Pass correct number of arguments - to delete-if-not. - - * erc.el(erc-update-current-channel-member): - Use erc-downcase when comparing - nick entries. Cleanup indentation. - -2003-11-01 Lawrence Mitchell - - * erc-sound.el: Added a (provide 'erc-sound) line. - - * erc.el(erc-cmd-NAMES): send to TGT, not CHANNEL. - -2003-10-29 Sandra Jean Chua - - * erc-pcomplete.el, erc.el, CREDITS: - Merged Jeremy Maitin-Shepard's patch for time-sensitive nick completion. - -2003-10-27 Mario Lang - - * Makefile, debian/changelog: - New Debian package 4.0.cvs.20031027 - -2003-10-25 Mario Lang - - * erc.el: Fix typo tuncate->truncate - -2003-10-24 Mario Lang - - * erc-dcc.el: From Stephan Stahl : - (erc-dcc-send-block): Kill buffer if transfer completed correctly. - -2003-10-22 Mario Lang - - * erc-track.el(erc-track-disable): - Do not deactivate all advices for `switch-to-buffer', - just disable the erc specific one. (Bug#217022). - -2003-10-18 Lawrence Mitchell - - * erc-log.el(erc-log-file-coding-system): New variable. - (erc-save-buffer-in-logs): Use it. - -2003-10-17 Mario Lang - - * erc.el(erc-interpret-mirc-color): New boolean defcustom - - * erc.el: Do not use -nowait on darwin (thanks johnw) - -2003-10-15 Lawrence Mitchell - - * erc.el(define-erc-module): - Set erc-FOO-mode appropriately in erc-FOO-enable - and erc-FOO-disable. - -2003-10-12 Jorgen Schaefer - - * erc-autoaway.el(erc-mode): - Reset idletime on connect. Fixes an annoying bug which - flooded the server with always on reconnect. - (erc-autoway-reset-idletime): Accept optional args so we can hook it - onto erc-server-001-hook. - -2003-10-10 Mario Lang - - * erc.el(erc-hide-list): Add a nice defcustom type - -2003-10-08 Mario Lang - - * Makefile, debian/changelog, debian/control: - Debian snapshot 20031008 - - * erc-speedbar.el: - Patch from Eric M. Ludlam : - - (erc-install-speedbar-variables): Add functions list (needs new speedbar?) - - (erc-speedbar-buttons): Add doc. Clear the buffer - - (erc-speedbar-sort-channel-members): New function. - - (erc-speedbar-expand-channel): Call new sort function. Change some visuals. - - (erc-speedbar-insert-user): Change some visuals based on channel data. - - (erc-speedbar-line-text, erc-speedbar-item-info): New functions - Add proper elisp file header. - -2003-10-02 Lawrence Mitchell - - * erc-match.el(erc-match-syntax-table): New variable. - (erc-match-current-nick-p): Use it. - - * erc.el(erc-quit-reason-zippy, erc-part-reason-zippy): Use - `erc-replace-regexp-in-string' rather than - `replace-regexp-in-string'. - (erc-command-indicator-face): New face, used to show commands if - `erc-hide-prompt' is nil and `erc-command-indicator' is non-nil. - (erc-command-indicator): Clean up doc-string. - (erc-display-prompt): New optional argument FACE, use this rather - than `erc-prompt-face' to fontify the prompt if non-nil. - (erc-send-current-line): Pass in `erc-command-indicator-face' to - `erc-display-prompt'. - - * erc-compat.el(erc-replace-regexp-in-string): New function. - Alias for `replace-regexp-in-string' on Emacs 21. - Argument massaging for `replace-in-string' for XEmacs. - -2003-09-28 Jorgen Schaefer - - * erc.el(erc-keywords): Removed. Wasn't used by anything. - -2003-09-25 Lawrence Mitchell - - * erc.el: ERC-HIDE-PROMPT: add custom group - ERC-COMMAND-INDICATOR: new variable. - ERC-COMMAND-INDICATOR: new function. - ERC-DISPLAY-PROMPT: new argument, PROMPT, used to override default - prompt. - ERC-SEND-CURRENT-LINE: pass ERC-COMMAND-INDICATOR to ERC-DISPLAY-PROMPT. - -2003-09-24 Jorgen Schaefer - - * erc.el(erc-parse-line-from-server): - Ignore empty lines as required by RFC. - -2003-09-17 Mario Lang - - * erc.el: Add lag time calculation - -2003-09-13 Mario Lang - - * Makefile, debian/README.Debian, debian/changelog: - New debian release - - * erc-notify.el: - Call erc-notify-install-message-catalogs on load, not on module init - - * erc.el(erc-update-modules): - Use `load' instead of `require'. XEmacs appears - to have the NOERROR arg only sometimes... Strange - - * erc.el: No fboundp if we have a defvar - - * erc.el: Properly defvar erc-ping-handler - -2003-09-11 Damien Elmes - - * erc.el(erc-setup-periodical-server-ping): - check if erc-ping-handler is - bound before referencing it - -2003-09-10 Mario Lang - - * erc.el(erc-cmd-NICK): - Warn about exceeded NICKLEN if we know it. - - * erc.el: Make erc-server-PONG obey erc-verbose-server-ping. - Cancel old `erc-ping-handler' timer when restablishing connection in the same - buffer. - - * debian/changelog, Makefile: New debian snapshot - - * erc-dcc.el, erc-xdcc.el: - Use new function erc-dcc-file-to-name to convert spaces to underscores - - * erc-xdcc.el: Add autoload for erc-xdcc-add-file - -2003-09-08 Mario Lang - - * erc-dcc.el: indent fixes and copyright update - - * erc.el: - erc-send-ping-interval: New defcustom which defaults to 60. - Every 60 seconds, we send PING now. - This should fix the "connection silently lost" bug. - Please test this change extensively, and report problems. - -2003-09-07 Alex Schroeder - - * erc.el(erc-default-coding-system): - Test for undecided and utf-8 - before setting. - -2003-09-01 Mario Lang - - * erc.el(erc-modules): Add some more symbols to the set - - * erc.el(erc-modules): Add :greedy t to the set in - - * erc-dcc.el: - More autoloads which make dcc autoload upon ctcp dcc query received. - - * erc-dcc.el(erc-cmd-DCC): Add Autoload. - (pcomplete/erc-mode/DCC): Ditto, makes DCC autoloadable just by using - completion. - Also only offer "send" if fboundp make-network-process. - - * erc-autojoin.el: Update copyright - - * erc-autojoin.el(erc-autojoin-add): - Only add the channel if it is not already there. - - * erc-notify.el: - Use `define-erc-module' instead of old `erc-notify-initialize'. - Now defines the global minor mode erc-notify-mode, and should also - be controllable via `erc-modules' with symbol `notify'. - - * erc.el(erc-modules): - Fix paren-in-column-zero bug in docstring. - Add a sort of bogus, but still better :type. - Add autojoin and netsplit by default. - (erc-update-modules): Don't barf with an error if `require' fails. - We can still error out if the mode is not defined. - -2003-08-31 Andreas Fuchs - - * erc.el: - * make 353 (NAMES reply) output go into the appropriate channel buffer - (if it exists) or into the active erc buffer (if not). - -2003-08-29 Marcelo Toledo - - * erc.el: - Added the variable erc-echo-notices-in-current-buffer to make possible display notices in the current buffer (queries to nickserv/chanserv/memoserv). Defaults to nil so nothing changes from what we have today. - -2003-08-29 Mario Lang - - * erc.el: Fix typo in varname which led to a compiler warning - - * AUTHORS: Added lawrence - -2003-08-27 Mario Lang - - * erc-dcc.el: - Set process and file-coding system to 'binary (for Windows) - - * erc-stamp.el: Rename custom group erc-timestamp to erc-stamp. - -2003-08-07 Lawrence Mitchell - - * erc-fill.el(erc-fill-disable): - Remove erc-fill, not erc-fill-static from - erc-insert-modify-hook. - -2003-08-05 Francis Litterio - - * erc.el(erc-send-current-line): - Now we display the prompt for previously entered commands - based on the value of customization variable erc-hide-prompt. This change is - closely related to the immediate previous version by wencem. - -2003-08-04 Lawrence Mitchell - - * erc.el(erc-send-current-line): - If we're sending a command, don't display - the prompt. - -2003-08-04 Damien Elmes - - * erc-track.el: patch from David Edmondson (dme AT dme DOT org) - - This patch makes button 3 on the erc-track buffer names in the - modeline show the selected buffer in another window. It's analogous to - button 2 which shows the buffer in the current window. - -2003-07-31 Francis Litterio - - * erc.el(erc-display-line-1): - Fixed bad indentation on one line. No semantic change. - -2003-07-29 Lawrence Mitchell - - * erc-match.el: - Quote open paren in docstring of erc-text-matched-hook - - * erc.el: Anchor match only at beginning in erc-ignored-user-p. - - * erc-button.el: New variable erc-button-wrap-long-urls. - Modified erc-button-add-buttons: - New optional argument REGEXP. - If we're buttonizing a URL and erc-button-wrap-long-urls is - non-nil, try and wrap them - - Modified erc-button-add-buttons-1: - Pass regexp to erc-button-add-buttons. - -2003-07-28 Francis Litterio - - * erc.el(erc-network-name): - Improved docstring. Removed an unnecessary call to erc-server-buffer. - -2003-07-28 Mario Lang - - * erc.el: By lawrence: - (erc-ignored-user-p): Use anchored regexp. - (smiley): Fix missing quote in `remove-hook' call. - -2003-07-26 Francis Litterio - - * erc-nets.el, erc-nickserv.el, erc.el: - Changed all references to Openprojects into references to Freenode. - -2003-07-25 Francis Litterio - - * erc.el: - Now variable erc-debug-irc-protocol is defvar'ed instead of defcustom'ed. - Made the docstring clearer too. - - * erc.el: Fixed a wrong-type-argument error from window-live-p. - -2003-07-15 Damien Elmes - - * erc-log.el(erc-log-setup-logging): - set buffer-file-name to "", as (basic-save-buffer) - will prompt for a buffer name before invoking hooks. the buffer-file-name - will be overridden by (erc-save-buffer-in-logs) anyway - the main danger - of doing this is write-file-contents hooks. Let's see if anyone complains. - (erc-save-buffer-in-logs): return t, so that further write hooks are not run - -2003-07-09 Damien Elmes - - * erc-dcc.el(erc-dcc-open-network-stream): - -nowait still crashes emacs cvs - disable for now - -2003-07-02 Francis Litterio - - * erc.el(erc): Minor docstring modification. - -2003-07-01 Damien Elmes - - * erc-match.el(erc-match-current-nick-p): - match only on word boundaries - - * erc-log.el(erc-log-setup-logging): - not sure how this crept in again - make sure we set - buffer-file-name to nil, since otherwise it is not possible to open - previous correspondence in another buffer while a conversation is open - -2003-06-28 Francis Litterio - - * erc.el(erc-network-name): - Now makes some intelligent guesses if the server didn't tell - us the network name. - -2003-06-28 Alex Schroeder - - * erc.el(erc-default-coding-system): Use utf-8 as the default - encoding for outgoing stuff and undecided as the default for - incoming stuff. - (erc-coding-sytem-for-target): New. - (erc-encode-string-for-target): Use it. - (erc-decode-string-from-target): Use it. Removed the flet - erc-default-target hack and documented the dynamically bound - variable `target' instead. - -2003-06-25 Francis Litterio - - * erc.el(erc-log-irc-protocol): - Now we keep point on the bottom line of the window - displaying the *erc-protocol* buffer if it is at the end of the - *erc-protocol* buffer. - - * erc.el: - Added some text to the docstring for variable erc-debug-irc-protocol. - -2003-06-23 Francis Litterio - - * erc-dcc.el(erc-dcc-auto-mask-p): - Fixed a docstring typo that caused a load-time error. - - * erc-dcc.el(erc-dcc-auto-mask-p): - Changed reference to undefined variable erc-dcc-auto-mask-list - to erc-dcc-auto-masks. - Changed default value of variable erc-dcc-auto-masks to nil and added text to its - docstring. - - * erc-notify.el(erc-notify-timer and erc-notify-QUIT): - Added network name to notify_off message. - - * erc.el(erc-network-name): - Now returns the name of the IRC server if the network name - cannot be determined. - - * erc-notify.el(erc-notify-JOIN and erc-notify-NICK): - Added argument ?m to call to erc-display-message. - - * erc-dcc.el(erc-dcc-do-LIST-command): - Fixed a bug where I assumed (plist-get elt :type) - returns a string -- it really returns a symbol. - - * erc-notify.el(erc-notify-timer): - Now we include the network name in the notify_on message. - - * erc.el: - New function: erc-network-name. Returns the name of the network that the - current buffer is associate with. Not every server sends the 005 messages - that enable the network name to be known. If the network name is - not known, the string "UNKNOWN" is returned. - - * erc-dcc.el(erc-dcc-chat-setup): - Added a comment. Fixed a bug where a DCC CHAT buffer has no - prompt when it first appears. - - * erc-dcc.el(erc-dcc-chat-parse-output): - Now a DCC chat buffer displays the nick using - erc-nick-default-face just like in a channel buffer. - -2003-06-22 Francis Litterio - - * erc.el(erc-display-prompt): - Fixed incorrect indentation. No semantic change. - - * erc.el(erc-strip-controls): - Minor change to regexp that matches IRC color control - codes. I was seeing usage as follows: ^C07colored text^C^C04other color. - Now we strip a ^C followed by zero, one, or two digits. Before this change, - we stripped a ^C followed by one or two digits. - - * erc-dcc.el(erc-dcc-do-LIST-command): - Improved format of output of /DCC LIST. Now the - "Size" column for a DCC GET includes the percentage of the file that has - been retrieved. - (erc-dcc-do-GET-command): Now it works if erc-dcc-default-directory is set. - -2003-06-19 Damien Elmes - - * erc-log.el: - * added quickstart information to the comments up the top - -2003-06-16 Mario Lang - - * erc.el: - Default to open-network-stream on MS Windows. (thanks lawrence) - -2003-06-11 Damien Elmes - - * erc.el(erc-process-input-line): - refactor so that wrong-number-of-arguments is - caught when using do-not-parse-args - this lets do-not-parse-args - commands display help messages on incorrect syntax in a uniform manner. - This no longer raises a bad-syntax error - was this a catch-all to stop a - backtrace? Does it belong? - (erc-cmd-APPENDTOPIC): the correct way to display help when you want to - accept an arbitrary string is to (signal 'wrong-number-of-arguments nil). - This fixes a bug where people could not /at topics with a space in them. - -2003-06-09 Damien Elmes - - * erc.el: - Re-add the last few changes which weren't merged for some reason. - - * erc.el(erc-cmd-APPENDTOPIC): show help when given no arguments - - Patch from MrBump. Fixes problem with erc-set-topic inserting ^C characters - into the topic. Also removes dependency on CL. - -2003-06-08 Jorgen Schaefer - - * erc.el: - Added comment to explain (eval-after-load "erc" '(erc-update-modules)). - -2003-06-01 Mario Lang - - * erc-pcomplete.el: Add completion for /unignore - -2003-05-31 Alex Schroeder - - * erc-compat.el(erc-encode-coding-string): The default binding, - if encode-coding-string was not available, must be a defun that - takes multiple arguments. Did that. - -2003-05-30 Mario Lang - - * erc.el: - Add handlers for 313 and 330 (by arne@rfc2549.org, thanks) - -2003-05-30 Damien Elmes - - * erc.el: - patch from MrBump to make /mode #foo +b work again (erc-cmd-BANLIST only - temporarily changes them now) - -2003-05-29 Alex Schroeder - - * erc.el(erc-select): - server is now defaulted with erc-compute-server. - A few cosmetic fixes. - (erc-default-coding-system): Renamed from erc-encoding-default. - (erc-encoding-default): Renamed to erc-default-coding-system. - (erc-encoding-coding-alist): Documentation updated to cover regexps. - (erc-encode-string-for-target): Now considers keys of - erc-encoding-coding-alist to be regexps. Rely on erc-compat - wrt. MULE support. - (erc-decode-string-from-target): New function. - (erc-send-current-line): eq -> char-equal fix. - (erc-server-TOPIC): topic is now decoded with - erc-decode-string-from-target. - (erc-parse-line-from-server): Line from server is no longer decoded - here. - (erc-server-PRIVMSG-or-NOTICE): Message from a user is decoded here, - sspec -> sender-spec for clarity. Cosmetic if -> when fix. - (erc-server-TOPIC): sspec -> sender-spec - (erc-server-WALLOPS): Ditto. - - * erc-compat.el(erc-decode-coding-string): - Now requires coding-system as an argument. - -2003-05-15 Mario Lang - - * erc.el: - erc-part|quit-hook is only run on a part|quit directed to our nick, reflect that in the docstring to avoid confusion - -2003-05-01 Andreas Fuchs - - * erc-truncate.el: - * erc-truncate-buffer-to-size: use fboundp. Scheme takes its toll... - -2003-05-01 Jorgen Schaefer - - * erc-truncate.el: remove require of erc-log - (erc-truncate-buffer-to-size): use erc-save-buffer-in-logs when it's - there, else, don't. - -2003-04-29 Andreas Fuchs - - * erc-log.el, erc-truncate.el, erc.el: erc.el: - * erc-cmd-QUIT: Remove references to code in erc-log.el, to - not force autoloading of erc-log.el - * erc-server-PART: ditto. - * erc-quit-hook: new hook, run when /quit command is - processed. - * erc-cmd-QUIT: use it. - * erc-part-hook: new hook, run then PART message is - processed. - * erc-cmd-PART: use it. - * erc-connect-pre-hook: new hook, run before connection to IRC - server is started. - * erc: use it. - * erc-max-buffer-size: Move truncation variables and functions - to erc-truncate.el - * erc-truncate-buffer-on-save: moved to erc-log.el - * erc-initialize-log-marker: new function. - * erc-log.el: - * erc-truncate-buffer-on-save: New defcust here; from erc.el - * erc-truncate-buffer-on-save: Put it in group `erc-log' - * erc-log-channels-directory: Remove trailing slash from - default value. - * Add functions to erc-connect-pre-hook, erc-part-hook and - erc-quit-hook to avoid getting autoloaded. - - * erc-truncate.el: - * Contains the truncation functions and defcusts from erc.el. - * define-erc-module clause added; new erc-truncate-mode. - -2003-04-29 Jorgen Schaefer - - * erc.el(erc): - Check whether erc-save-buffer-in-logs is bound, too - - * erc.el(erc): - Check whether erc-logging-enabled is bound before using it - not - everyone is using erc-log.el! - -2003-04-28 Andreas Fuchs - - * erc-log.el: - * while we're at it, remove the (declare (ignore ignore)) statements. - - * erc-log.el: - * add autoload statement for erc-log-mode/etc. Sorry for the delay. - - * erc-log.el, erc.el: * erc.el: - - move variables and functions to erc-log.el: - defgroup `erc-log' - defcustom `erc-log-channels-directory' - defcustom `erc-log-insert-log-on-open' - defcustom `erc-generate-log-file-name-function' - defun `erc-save-buffer-in-logs' (autoloads from erc-log.el) - defuns `erc-generate-log-file-name-*' - defun `erc-current-logfile' - defun `erc-logging-enabled' (autoloads from erc-log.el) - - erc-truncate-buffer-to-size: fix for double-saving bug when - writing out truncated buffer contents. Thanks, lawrence mitchell ! - - erc-remove-text-properties-region: Fix case for read-only text. - - erc-send-current-line: update insert-marker before calling the hooks. - also, wrap (erc-display-prompt) so that it doesn't toggle - buffer-modified-p. - - erc-interpret-controls: remove /very/ old commented-out function - - erc-last-saved-position: make it a marker - - erc: use it. - - * erc-log.el: (thanks, lawrence mitchell !) - - Move logging code from erc.el here - - define-erc-module log: add; minor mode erc-log-mode is the - same as adding the `erc-save-buffer-in-logs' to - erc-send-post-hook and `erc-insert-post-hook'. - - erc-w32-invalid-file-characters: add. - - erc-enable-logging: add. - - erc-logging-enabled: use it. - - erc-logging-enabled: autoload. - - erc-save-buffer-in-logs: fix for truncating saved buffer with read-only text. - - erc-save-buffer-in-logs: use erc-last-saved-position. - - erc-save-buffer-in-logs: fix saving half-written messages on - the prompt when saving the log file. (simply uses - erc-insert-marker as an upper bound for saving). - -2003-04-27 Damien Elmes - - * erc.el: erc-modules: added - -2003-04-27 Alex Schroeder - - * Makefile(UNCOMPILED): Added erc-compat.el. - (clean): Remove .elc files, too. - Patch by Hynek Schlawack - -2003-04-22 Damien Elmes - - * erc-button.el: - erc-button-keymap: set the parent keymap to erc-mode-map - -2003-04-20 Damien Elmes - - * erc.el: - erc-official-location: shouldn't the official location be the base URL of erc? - - * erc.el: - erc-modules: updated the docstring to make the semantics clearer - -2003-04-19 Mario Lang - - * erc.el: - Fix problem where % in NOTICE produced errors (from mmc) - -2003-04-18 Damien Elmes - - * erc.el(erc-toggle-debug-irc-protocol): - moved a reference to 'buf' inside the let - statement which defines it. it's difficult to tell what the original - intentions were here - at the moment the debug window is displayed when - toggling either way. - - * README, erc.el: - (erc-update-modules: added a condition in for erc-nickserv -> erc-services - - * erc-pcomplete.el: - - that change to erc-update-modules making it require the modules first means - we don't need any special case handling here, so i reverted the previous - change - - * erc.el: - - don't require 'erc-auto, since windows users don't have access to make. - instead, we handle it in (erc-update-modules) - -2003-04-17 Damien Elmes - - * README, Makefile: - Updated Makefile and documentation to reflect the new release - - * erc.el: - - note the previous change also updated the release number to erc 4.0! - (erc-connect): fix a bug introduced by the previous release - - * erc.el: - fixed about 20 instances of (message (format ...)) which will break if the - format returns a string with %s in it - - * erc.el: erc-error-face: make it red, not pink - - * erc-pcomplete.el: - since pcomplete is autoloaded via erc-completion-mode, and completion is in - erc-modules by default, we remove completion when pcomplete is added - - * erc.el(define-erc-module): no need for delete, use delq - - * erc-members.el(erc-nick-channels): - (erc-person-channels) takes one arg - (erc-format-user): again, they all take an arg - - * erc.el: - - require erc-auto when loading, so the default `erc-modules' can be loaded. - this makes erc-auto no longer a convenience but a necessity - all the name - of user friendliness. - (define-erc-module): the enable and disable routines now update erc-modules - accordingly - erc-modules: new variable controlling the modules which erc has loaded/will - load. when customizing, it will automatically enable modules. it won't - automatically disable modules which are removed, yet. - (erc-update-modules): enable all modules in `erc-modules' - - * erc-dcc.el(erc-dcc-open-network-stream): - use the -nowait equiv if available - erc-dcc-server-port: removed - erc-dcc-port-range: allows a range of values, so you can have more than one - dcc - (erc-dcc-server): support erc-dcc-port-range - (erc-dcc-chat): use OCHAT for outgoing chat for now. we need to fix the - issues with allowing more than one chat with the same person - - * erc.el: - erc-log-channels: removed; set the directory to start logging - (erc-directory-writeable-p): create directory if it doesn't exist, check if - it's writable - (erc-logging-enabled): don't reference erc-log-channels - -2003-04-07 Damien Elmes - - * erc.el(erc): - but when inserting the contents of a previous logfile, use the logfile - name, not ""! - - * erc.el(erc): - set buffer-file-name to "", since we have a custom saving function and - it's not needed. this enables one to open a log file with previous - correspondence, while talking to the person at the same time - -2003-03-29 Francis Litterio - - * erc.el(erc-prepare-mode-line-format): - Now strips all text properties from the target before - putting it in the mode line. Keeps the mode line looking consistent. - (erc-channel-p): Improved docstring. - -2003-03-28 Alex Schroeder - - * erc.el(erc-generate-log-file-name-with-date): New function. - (erc-generate-log-file-name-function): Make it available. - -2003-03-24 Mario Lang - - * erc.el: - Fix erc-prompt and erc-user-mode custom :type (Closes: #185794) - -2003-03-20 Damien Elmes - - * erc.el: - erc-server-hook-list: correct documentation of ordering of (proc parsed) - -2003-03-16 Alex Schroeder - - * erc-track.el(erc-modified-channels-string): - Make it a risky-local-variable. - -2003-03-16 Jorgen Schaefer - - * erc-track.el(erc-track-modified-channels): - Use (point-min) if we don't find a - parsed-property, so it won't error out with nil... - -2003-03-16 Damien Elmes - - * erc-track.el(erc-track-switch-buffer): - removed call to erc-modified-channels-update, as - this is done correctly on buffer switching in both emacs and xemacs now - -2003-03-15 Damien Elmes - - * erc-track.el(erc-find-parsed-property): - simplified a little, so it shouldn't return nil anymore - - * erc.el: erc-send-post-hook: document narrowing which occurs - -2003-03-14 Alex Schroeder - - * erc-track.el(erc-find-parsed-property): New function. - (erc-track-modified-channels): Use it instead of relying on - point-min. - -2003-03-12 Mario Lang - - * erc.el: - Fix erc-set-topic to accept a channel name as first word - -2003-03-11 Jorgen Schaefer - - * erc-dcc.el: - Small patch (<10 lines, also slightly modified by Jorgen Schäfer) from - David Spreen to add hostmask-authentication to - DCC auto-accept. - - erc-dcc-auto-mask-list: New variable - (erc-dcc-handle-ctcp-send): Check erc-dcc-auto-mask-list - (erc-dcc-auto-mask-p): New function - erc-dcc-send-request: Docstring now mentions erc-dcc-auto-mask-list - -2003-03-10 Francis Litterio - - * erc-ring.el(erc-clear-input-ring): - New function. Erases the contents of the input ring for - the current ERC buffer. - -2003-03-08 Francis Litterio - - * erc.el: - (erc-display-line-1) and (erc-send-current-line): Now these functions reset erc-insert-this - to t as soon as possible after consuming the value of that variable. See the comments in - the code for the strange symptom this fixes. - (erc-bol): Changed to call point-at-eol instead of line-end-position. This increases XEmacs - portability, since XEmacs doesn't have line-end-position. Patch suggested by Scott Evans - on the ERC mailing list. - -2003-03-04 Damien Elmes - - * erc.el: banlist*: patch from mrbump to avoid using cl packages - -2003-03-04 Francis Litterio - - * erc.el: - Changed erc-noncommands-list from a constant to variable, so that users can - add their own erc-cmd-* functions to the list. Improved the docstring too. - -2003-03-02 Francis Litterio - - * erc.el(erc-server-353): - Now the output of "/NAMES #channel" appears in the currently - active ERC buffer, even if the user is not a member of #channel. - - * erc.el(erc-cmd-DEOP): - Fixed a syntax error: invalid read syntax ")" caused by my last change. - -2003-03-01 Francis Litterio - - * erc.el(erc-cmd-DEOP): - Fixed a wrong-type-argument error caused by calling split-string - on a list instead of on a string. Removed the call to split-string entirely, - because it wasn't needed. - - * erc.el(erc-cmd-HELP): - Changed to use intern-soft instead of intern. Now "/HELP floob" - doesn't create a void function symbol erc-cmd-FLOOB. - -2003-02-25 Damien Elmes - - * erc.el(erc-cmd-SERVER): - remove erroneous references to line, use server instead - -2003-02-23 Francis Litterio - - * erc.el(erc-toggle-debug-irc-protocol): - Fixed a bug where the global value of - kill-buffer-hook was being modified instead of the buffer-local value. - -2003-02-22 Francis Litterio - - * erc.el(erc-cmd-KICK): - Now supports any number of words in the REASON string. Examples - of the /KICK command are: - /KICK franl You don't belong here - /KICK franl Bye - /KICK franl - /KICK #channel franl Go away now - /KICK #channel franl Bye - /KICK #channel franl - -2003-02-16 Jorgen Schaefer - - * erc-stamp.el(erc-insert-timestamp-right): - Make the timestamp rear-nonsticky, so - C-e works at the beginning of the next line. - -2003-02-16 Andreas Fuchs - - * erc-stamp.el: - * s/choose/choice/ in customize options, as kensanata requested. - -2003-02-15 Francis Litterio - - * erc.el(erc-toggle-debug-irc-protocol): - Now if the *erc-protocol* buffer is killed, - logging is turned off. Prior to this change, the buffer would come back - into existence (generally unbeknownst to the user) after being killed. - -2003-02-11 Damien Elmes - - * erc.el(erc-send-current-line): - we can't inhibit everything here when not connected, - as the user will expect commands like /server still to work. the - erc-cmd-handler should recover from errors instead - -2003-02-10 Damien Elmes - - * erc.el: - * we now run erc-after-connect on 422 (no motd) messages as well as the motd - messages - (erc-login): revert the previous change - - * erc.el(erc-login): register that we're connected - -2003-02-10 Mario Lang - - * erc-members.el: * Provide erc-members - * Fix excessive ) - * Comment out broken self-tests - -2003-02-07 Damien Elmes - - * erc.el(erc-connect): - notify the user we're trying to connect when using asych - connections - - * erc.el(erc-connect): support an asynchronous connection - (erc-process-sentinel): ditto - - * erc-track.el: - * advise switch-to-buffer in the case of xemacs, since it doesn't have - window-configuration-change-hook - - * erc.el(erc-send-current-line): - if not connected, refuse to send either a message or - a command - - * erc.el: (erc-save-buffer-in-logs): - - check for a sensible region before saving the buffer. if the - connection process is killed early on, there is not a sensible region - to save - - don't set buffer-file-name on save. we don't need it, and it means we - can now find-file a log while an existing query is open with that - user - - * erc.el(erc-process-input-line): - when displaying the help for a function, if no - documentation exists, don't fall over - (erc-cmd-SAY): new function for quoting lines beginning with / - (erc-server-NICK): - - fix a bug where the "is now known as" message doesn't appear on newly - created /query buffers - - when a user changes their nick, update the query to point to the new - nick - - * erc.el(erc-send-current-command): - don't reject multi-line commands. since - multiline-p is used as the no-command arg to erc-process-current-line, - multi-line text is never interpreted as a command. i believe this is the - correct behavior - it allows people to post the output of things like df - (sans header). if you want to change this, please provide a rationale - in the changelog - - * erc.el(erc-send-current-line): - only match the first line when determining if a - multi-line command is allowed - -2003-02-07 Jorgen Schaefer - - * erc-bbdb.el(erc-bbdb-highlight-record): - Use alternate strings, not character - classes to split the nick-field. - -2003-02-06 Francis Litterio - - * erc.el(erc-process-sentinel): - Now we set erc-connected to nil every time we disconnect - from a server, not just when an unexpected disconnect happens. - - * erc.el(erc-connected): - Removed redundant defvar of this variable. Improved the - docstring. - (erc-login): Changed to send a correct RFC2812 USER message (see section - 3.1.3 of RFC2812 for the documentation of the semantics of each argument - of the USER message. - -2003-02-02 Damien Elmes - - * erc.el(erc-cmd-NOTICE): fix from mrbump - -2003-01-31 Francis Litterio - - * erc.el(erc-cmd-JOIN): - Now we only send one JOIN command to the server when a channel - key is provided. - -2003-01-30 Francis Litterio - - * erc.el(erc-remove-channel-member): - Fixed so that it runs erc-channel-members-changed-hook - with the channel buffer current, as is documented in the docstring for variable - erc-channel-members-changed-hook: "The buffer where the change happened is - current while this hook is called." - -2003-01-28 Francis Litterio - - * erc.el: - (erc-ignored-user-p),(erc-cmd-IGNORE),(erc-cmd-UNIGNORE): Now nicks are ignored - on a per-server basis. Now, erc-ignore-list is only valid in server - buffers! Do not reference it in channel buffers. - - * erc.el(erc-cmd-IGNORE): - Now says "Ignore list is empty" if it erc-ignore-list is empty - instead of showing an empty list. - -2003-01-25 Alex Schroeder - - * erc-nickserv.el(services): Defined a module - -2003-01-25 Jorgen Schaefer - - * erc.el(erc-process-ctcp-query): - Display recipient of CTCP query if it's not - our current nick. - - * erc.el(erc-cmd-WHOIS): - Accept an optional second argument SERVER. - -2003-01-25 Alex Schroeder - - * erc-stamp.el(stamp): erc-add-timestamp must always be added - with the APPEND parameter -- not only when adding it on the right. - -2003-01-24 Alex Schroeder - - * erc-members.el(erc-channel-members-changed-hook): Obsolete, use - erc-members-changed-hook instead. When it is set, add its content - to erc-members-changed-hook. - (erc-update-channel-member): Obsolete, use erc-update-member - instead. Defalias to that effect. - (erc-remove-channel-member): New and already obsolete. Use - erc-remove-nick-from-channel instead. - (erc-update-channel-info-buffer): Obsolete, use ignore instead. - Yes, these have to go. - (erc-channel-member-to-user-spec): Obsolete, use erc-format-user - instead. - (erc-format-user): New. - (erc-ignored-reply-p): New, use it. - - * erc-members.el: - Further along the way. Any function from erc.el that uses - channel-members should end up in this file, rewritten to use - erc-members. - - (erc-person): Call erc-downcase before getting - something from the hash. - (erc-nick-in-channel): Checking whether erc-process must be used is - unnecessary -- this will be done in erc-person. - (erc-nick-channels): New. - (erc-add-nick-to-channel, erc-update-member): Call erc-downcase - before putting something into the hash. - (erc-buffer-list-with-nick): New. - (erc-format-nick, erc-format-@nick): New, backwards incompatible. - Must check for other places that call these! - (erc-server-PRIVMSG-or-NOTICE): Use the new version. - - * erc-compat.el(view-mode-enter): defalias to view-mode, if - view-mode-enter is not fboundp and view-mode is -- as is the case - in XEmacs. We need view-mode-enter in erc-match.el. - -2003-01-23 Francis Litterio - - * erc.el(erc-default-server-handler): - Minor performance improvement: allow the lambda - expression to be byte-compiled. - -2003-01-23 Damien Elmes - - * erc.el(erc-cmd-BANLIST): - in the absence of a fill-column, use the screen width - -2003-01-22 Damien Elmes - - * erc.el: - patch from MrBump to delay fetching the banlist until /bl is run, so we don't - fetch it when joining a channel anymore - - * erc-ring.el: - * instead of adjusting hooks when loaded, provide (erc-ring-mode). you'll - need to run (erc-ring-mode 1) now to get the ring - * (erc-previous-command), (erc-next-command): - - check if the ring exists and create it if necessary - - don't do anything if the ring is empty - - * erc-pcomplete.el: - Put "how to use" documentation in the comments up the top - -2003-01-21 Alex Schroeder - - * erc-autojoin.el(erc-autojoin-version): New. - - * erc-autojoin.el(erc-autojoin-add): Added body. - (erc-autojoin-remove): Added body. - (erc-autojoin): Provide it. - -2003-01-21 Damien Elmes - - * erc.el: erc-cmd-*: removed a bunch of references to force - -2003-01-21 Alex Schroeder - - * erc-autojoin.el(erc-autojoin-channels-alist): More doc. - -2003-01-20 Alex Schroeder - - * erc-autojoin.el: - new, based on resolve's mail, and the stuff on the wiki - - * erc-members.el: new - -2003-01-19 Mario Lang - - * debian/README.Debian, debian/changelog, debian/scripts/install, - debian/scripts/startup.erc, Makefile: - Prepare for 20030119 debian package - - * erc-dcc.el: - * (erc-decimal-to-ip): Since XEmacs decides that return a completely - and utterly wrong number from string-to-number if it is larger than - the integer boundary, instead of sanely converting the thing to - a float, we now (concat dec ".0"). - - - * erc.el: - * (erc-log-irc-protocol): Use erc-propertize, not propertize - -2003-01-19 Alex Schroeder - - * erc-button.el(erc-button-add-buttons): Added regexp-quote for - the list case, too. - -2003-01-19 Damien Elmes - - * erc-dcc.el(erc-dcc-member): fix for case where a prop is nil - - * erc-dcc.el(erc-dcc-member): - fix for xemacs's version of plist-member - -2003-01-19 Mario Lang - - * erc-notify.el: Delete empty strings from the ison-list - - * erc-track.el: - * (erc-track-switch-buffer): Call erc-modified-channels-update here. - - * erc-track.el: * toplevel: require 'erc-match - - * erc-track.el: * (erc-track-mode): Make autoload interactive - - * erc-button.el: * (button): Make the autoload interactive - - * erc.el: - * (erc-mode): Comment out the case-table stuff, breaks xemacs - * (erc-downcase): Revert. - - * erc-dcc.el: - * (erc-dcc-handle-ctcp-send): Use erc-decimal-to-ip on the ip we get... - - * erc-speak.el: - Eliminate reference to erc-nick-regexp, which no longer exists - -2003-01-19 Alex Schroeder - - * erc-stamp.el(erc-timestamp-right-column): New, default nil. - (erc-insert-timestamp-right): Use it, if non-nil. Verbose - doc string. - -2003-01-18 Jorgen Schaefer - - * erc.el(erc-downcase): Use the old behavior in non-CVS Emacs. - - * erc.el(erc-cmd-QUIT): Remove &rest. The correct fix follows. - (erc-cmd-GQUIT): Pass "" to erc-cmd-QUIT. - (erc-mode): Use the case-table only in CVS Emacs. See comment. - - * erc.el(erc-cmd-QUIT): make reason optional. - - * erc.el(erc-cmd-GQUIT): Fixed typo. - -2003-01-17 Mario Lang - - * erc.el: - * (erc-current-logfile): call expand-file-name, so that downcase doesn't mess up ~ - - * erc.el: * (erc-mode): Define a proper case-table. - * (erc-downcase): just call downcase for now, let's see if the case-table is portable, if yes, we'll remove all erc-downcase references anyway... - - * erc-button.el: * (erc-button-add-buttons): regex-quote the nick - -2003-01-17 Alex Schroeder - - * erc-button.el(button): erc-channel-members-changed-hook no - longer has erc-recompute-nick-regexp. - (erc-button-alist): Use channel-members instead of - erc-nick-regexp. - (erc-button-add-buttons): Split some code into - erc-button-add-buttons-1, and now handle strings, lists, and - alists. Regular expressions in lists and alists are enclosed in - < and >. - (erc-button-add-buttons-1): New. - (erc-nick-regexp): Deleted. - (erc-recompute-nick-regexp): Deleted. - - * erc-button.el: Remove require cl again. - (erc-mode-map): No longer bind widget-backward and widget-forward. - (erc-button-alist): Explain why byte-compiling makes no sense, and - remove all calls to byte-compile. - (erc-button-keymap): Define it the standard way, without exposing - the list nature of the keymap. - (erc-button-marker-list): Deleted. - (erc-button-add-buttons): Simplify. In particular, create the - button using the real callback, instead of using the intermediate - erc-button-push, and only store the data as described for - erc-button-alist. - (erc-button-remove-old-buttons): Simplify. No more list munging. - Instead, just remove all the properties that we add in - erc-button-add-button. - (erc-widget-press-button): Deleted. - (erc-button-click-button): New, for mouse clicks. Moves point to - where the mouse is, and calls erc-button-push. - (erc-button-push): Instead of matching again, just use the - erc-callback and erc-data properties at point to do the right - thing. - (erc-button-entry): Deleted. - (erc-button-next): Use error instead of the beep plus message - combo. - -2003-01-17 Jorgen Schaefer - - * erc-autoaway.el(erc-autoaway-set-back): - Don't pass a force argument to erc-cmd-GAWAY. - - * erc.el(erc-cmd-AWAY): Removed usage of the force variable. - -2003-01-17 Alex Schroeder - - * erc-button.el(button): - erc-recompute-nick-regexp is no longer added to - erc-channel-members-changed-hook unconditionally, but only if - erc-button-mode is enabled, and if it is disabled, it is removed - again. - (erc): Require cl for delete-if. - (erc-button-remove-old-buttons): Rewrote using delete-if to - prevent excessive consing. Having the marker list is still ugly, - so another solution needs to be found. - -2003-01-17 Jorgen Schaefer - - * erc.el(erc-banlist-store): - Don't assume there's always a setter in the banlist reply. - -2003-01-17 Alex Schroeder - - * erc-button.el(erc-button-url-regexp): Changed regexp according - to a suggestion by Max Froumentin . - -2003-01-17 Mario Lang - - * erc.el: - fix erc-remove-channel-member again to not error out on nil as first arg... - - * erc.el: * (erc-occur): New function - -2003-01-17 Damien Elmes - - * erc.el: erc-banlist-*: return nil so further hooks are called - - * erc.el(erc-server-368): - suppress "end of ban list" messages - use /listbans now - - * erc.el(erc-send-current-line): - removed the check for leading whitespace again - the - only time we want to prohibit multi-line commands is if / is the first - thing on the line - (erc-get-arglist): new defun for reading a function's arglist which should - work with older copies of emacs. we use help-function-arglist if it's - available, though, since that has support for reading subrs, etc - - * erc.el(erc-cmd-JOIN): fixed (again) - - * erc.el: * fixed call to erc-cmd-NICK when connecting - * support for listing bans and mass unbanning, again thanks to MrBump - - * erc.el(erc-set-topic): - patch from MrBump (Mark Triggs, mst@dishvelled.net) to strip - control chars and topic attribution in C-c C-t - -2003-01-16 Mario Lang - - * erc.el: - * (erc-remove-channel-member): Do not use delq, modify the list using setcdr like delq does. - In theory, this should be way faster since the list doesn't get traverse two times. - Measurement didn't show any real difference though :(, this system is flawed for channels with >300 users it seems... - Also moved some defcustoms up. - -2003-01-16 Brian P Templeton - - * erc.el: moved misplaced paren - -2003-01-16 Damien Elmes - - * erc.el(erc-cmd-UNIGNORE): - reference argument directly - no string matching - - * erc.el(erc-extract-command-from-line): - hmm, thinko in the canonicalization. should - be fixed - -2003-01-16 Francis Litterio - - * erc.el(erc-send-current-line): - Changed the regexp used to match /COMMANDs so that leading - whitespace is taken into account. - -2003-01-16 Mario Lang - - * erc-dcc.el: * (erc-dcc-do-SEND-command): Fix it - - * erc-ezbounce.el, erc-lang.el: Arglist changes... - - * erc.el: Various docstring fixes and additions. - - * erc-notify.el: - * (erc-cmd-NOTIFY): Change the function arglist to (&rest args) - - * erc-netsplit.el: * (erc-cmd-WHOLEFT): Has no args... - -2003-01-16 Damien Elmes - - * erc-fill.el: - erc-fill-column: default to 78, so things like docstrings don't get wrapped - in an ugly manner - -2003-01-16 Mario Lang - - * erc.el: - * (erc-cmd-default): Take a substring, now /mode works again. - * (erc-cmd-AWAY): Put do-not-parse-args t - * (erc-cmd-GAWAY): Ditto, and fix it. - * (erc-cmd-CTCP): Switch to argument system. - * (erc-cmd-KICK): Do the same. - -2003-01-15 Mario Lang - - * erc-dcc.el: - * (erc-cmd-DCC): Fixed for the new scheme, simplified. - * (erc-dcc-do-CHAT-command): Ditto. - * (erc-dcc-do-CLOSE-command): Ditto. - * (erc-dcc-do-LIST-command): Ditto. - -2003-01-15 Damien Elmes - - * erc.el: - erc-error-face: setting a background doesn't work so well with multi-line - messages, so we don't. fg color is negotiable ;-) - (erc-cmd-QUERY): fixed, new doco, suppress (erc-delete-query) until we fix it - (erc-send-current-line): allow multi-line messages provided they don't start - with a slash - there's no need to prohibit them if the slash isn't the - first character - - * erc.el: * bad-syntax now reports like incorrect-args - * bunch of extra cmds fixed, nick, sv etc. - - * erc.el(erc-cmd-HELP): fixed - (erc-extract-command-from-line): when determining canon-defun, make sure we - have a valid symbol - (erc-cmd-KICK): fixed - - * erc.el: - * removed duplicate do-no-parse-args properties for the defaliased defuns - (erc-process-input-line): show function signature when incorrect args - (erc-extract-command-from-line): canonicalize defaliases before extracting - plist - (erc-cmd-CLEAR): fixed - (erc-cmd-UNIGNORE): fixed again - - * erc.el(erc-cmd-SET): fixed - (erc-cmd-UNIGNORE): fixed - (erc-process-input-line): report when incorrect arguments are provided to a - command, and show the command's docstring - - * erc.el(erc-cmd-APPENDTOPIC): fixed - (erc-process-input-line): more informative error message than 'bad syntax' - -2003-01-15 Mario Lang - - * erc.el: * (erc-cmd-IGNORE): fixed - - * erc.el: * (erc-cmd-NAMES): fixed - - * erc.el: - * (erc-cmd-CLEARTOPIC): Simplify, fix doc, make interactive - -2003-01-15 Damien Elmes - - * erc.el(erc-cmd-JOIN): - correct invite behavior, and document it. - -2003-01-15 Mario Lang - - * erc.el: * (erc-cmd-PART): Put 'do-not-parse-args t - -2003-01-15 Damien Elmes - - * erc.el(erc-cmd-JOIN): new cmd argument syntax - (erc-process-input-line): check if (erc-extract-command-from-line) returned a - list, and apply if that's the case - - * erc.el: - erc-cmd-*: remove optional force and references to `force' in the code - (erc-cmd-AMSG): call erc-trim-string, not trim-string - -2003-01-15 Mario Lang - - * erc.el: - * (erc-cmd-CLEARTOPIC): LINE is now ARGS and already parsed. - Set erc-cmd-TOPIC to 'do-not-parse-args for now. - (comment: I think we should have 'first, so that only first word is parsed... - Or we could autodetect erc-channel-p in the parser before that somehow...) - - * erc.el: * (erc-cmd-OP): LINE is PEOPLE now, and already parsed. - - * erc-notify.el: - * (erc-cmd-NOTIFY): Arg LINE is now ARGS, and already parsed. - -2003-01-15 Jorgen Schaefer - - * erc-stamp.el(erc-insert-timestamp-right): - Prefer erc-fill-column to window-width, - because on wide screens the timestamp could wander off too far to the - right. - -2003-01-15 Mario Lang - - * erc.el: This is the "everything is suddenly broken!" release - You know, this is CVS, you can still go back, and wait until the transition - is finished, but here is patch one, which basically breaks every command - which is typed on the prompt. - Hit me, we can still revert, but something needs to be done about this. - * (erc-extract-command-from-line): intern-soft the function here. - If the function symbol has a property 'do-not-parse-args, operate as before, - otherwise, split the arguments prior to calling the command handler. - * (erc-process-input-line): Updated to accommodate the change above. - * (erc-send-distinguish-noncommands): Ditto. - * (erc-cmd-NAMES): Ditto. - * (erc-cmd-ME): Put 'do-not-parse-args property. - - * erc-dcc-list: Renamed - * (erc-dcc-member). Treat :nick as either a nick!user@host or nick, - do appropriate comparisons, simplified. - * (erc-dcc-list-add): New functions - various callers of (cons (list ...) erc-dcc-list) updated. - Other stuff I'm too bored to document now - -2003-01-15 Jorgen Schaefer - - * erc-stamp.el(erc-insert-timestamp-right): - Removed redundant code that overrid the - window-width. Now subtracts (length string) from every found - indentation positions. - -2003-01-14 Mario Lang - - * erc.el: - * (erc-cmd-AMSG): Remove useless call to erc-display-message. - - * erc-dcc.el: - * erc-dcc-chat/send-request: New variables, control how to treat - incoming dcc chat or send requests. Can be set to 'ask, which behaves - like it did before, 'auto, which accepts automatically, and - 'ignore, which ignores those type of requests completely. - * (erc-cmd-CREQ): New user-level command. - * (erc-cmd-SREQ): Ditto. - - * erc.el: * (erc-cmd-AMSG). New command. - - * erc-xdcc.el: * (erc-xdcc): delete empty strings from ARGS - - * erc-dcc.el: * erc-dcc-ipv4-regexp: New constant - * (erc-ip-to-decimal): Use it. - * erc-dcc-host:valid-regexp erc-dcc-ipv4-regexp: - * erc-dcc-host: :type - * (pcomplete/erc-mode/DCC): Add completion for GET and CLOSE. - * Some docstring/comment fixes. - - * erc-stamp.el: - * (erc-insert-timestamp-right): Subtract (length string) from - POS in any case, otherwise, linewrap occurs. - - * erc-dcc.el: - * Fixed the unibyte-multibyte problem (now a dcc get buffer is (set-buffer-multibyte nil), - and saves correctly (tried with 21.3.50)). Thanks to Eli for suggesting it! - * Added :start-time plist property/value to GET handling so that we can calculate elapsed-time. - * Some (unwind-protect (progn (set-buffer ...) ...)) constructs replaced with (with-current-buffer ...) - -2003-01-13 Mario Lang - - * erc-xdcc.el: - * erc-xdcc-help-text: New variable which makes replies to the originator - much more flexible. - * erc-xdcc-help-format: Removed. - * (erc-xdcc-help): Handle the new variable. - * (erc-xdcc): Simplified - - * erc-xdcc.el: * erc-xdcc-handler-alist: New variable. - * (erc-xdcc): Move code for list and send sub-commands into - * (erc-xdcc-help): New function. - * (erc-xdcc-list): New function. - * (erc-xdcc-send): New function. - -2003-01-12 Jorgen Schaefer - - * erc.el(erc-server-JOIN): - Oops, send MODE command only when *we* joined a channel. - - * erc.el: - Fixing ERCs behavior wrt IRCnet's !channels have a different name for - JOIN than in reality (e.g. you can join !forcertest or !!forcertest - and really get to !ABCDEforcertest) - - (erc-cmd-JOIN): Removed erc-send-command MODE. - (erc-server-JOIN): Ask for MODE now. - -2003-01-12 Damien Elmes - - * erc-dcc.el: - (erc-dcc-get-filter), (erc-dcc-get-file): store size as a string, not an - integer. check size > 0 for the case where a size wasn't provided, since - string-to-int will return 0 on an empty string - -2003-01-12 Mario Lang - - * erc-dcc.el: * Use RAWFILE arg with find-file-noselect - * Fix alist/plist conversion left-over - * Add verbose-info about sending blocks. - -2003-01-11 Mario Lang - - * erc-dcc.el: * (pcomplete-erc-mode/DCC): Fixes - - * erc-xdcc.el: Initial version. - - * erc-pcomplete.el: - * (erc-pcomplete): Fix so that cycle-completion works again. - * (pcomplete-parse-erc-arguments): If there is a space after the last word - before point, we need to return a "" arg, and it's position. - - * erc-dcc.el: Fix to pcomplete/erc-mode/DCC - - * erc-dcc.el: * (pcomplete/erc-mode/DCC): New function - - * erc-dcc.el: *** empty log message *** - - * erc-dcc.el: Move code around, just basic changes - -2003-01-11 Jorgen Schaefer - - * erc-stamp.el(erc-insert-timestamp-right): - Check whether erc-fill-column is - available before using it. Else default to fill-column or if - everything else fails, the window width of the current window. For the - fill-columns, use them directly as the starting position for the - timestamp. - -2003-01-11 Andreas Fuchs - - * erc-stamp.el: - erc-insert-timestamp-right: use correct window's window-width. If - buffer is not in a window, use erc-fill-column. - -2003-01-11 Mario Lang - - * erc-dcc.el (erc-dcc-do-LIST-command): Fix - - * erc-dcc.el: - * buffer-local variables erc-dcc-sent-marker and erc-dcc-send-confirmed marker removed - Keep This info in erc-dcc-member :sent and :confirmed plist values - :buffer plist for :type 'SEND removed, since we can get this with (marker-buffer - * erc-dcc-send-connect-hook: New hook, defaults to erc-dcc-send-block and erc-dcc-send-connected, which now prints a msg... - - * erc-dcc.el: - * (erc-dcc-chat-accept): Renamed from erc-dcc-chat. Callers updated. - * (erc-dcc-chat): Renamed from erc-dcc-chat-request. - Callers updated, and interactive form added. - * (erc-dcc-server-accept): No longer do any type-specific stuff. - * (erc-dcc-chat-sentinel): Call erc-dcc-chat-setup if event is "open from " - from here, otherwise call erc-dcc-chat-close. - - * ( - - * erc-dcc.el: *** empty log message *** - - * erc-dcc.el: Moved some functions around. - Doc string fixes. - "/dcc send nick filename" works now - -2003-01-11 Alex Schroeder - - * erc.el(erc-send-command): Fixed flood protect message. - - * erc-button.el(erc-button-syntax-table): Make `-' a legal nick - constituent. - -2003-01-10 Mario Lang - - * erc-dcc.el: Some more steps toward dcc send. - -2003-01-10 Francis Litterio - - * erc-notify.el(erc-notify-timer): - Changed to make it IRC-case-insensitive when comparing nicks. - (erc-notify-JOIN): Changed to make it IRC-case-insensitive when comparing nicks. - (erc-notify-NICK): Changed to make it IRC-case-insensitive when comparing nicks. - (erc-notify-QUIT): Changed to make it IRC-case-insensitive when comparing nicks. - (erc-cmd-NOTIFY): Now "/notify -l" lists the nicks on your notify list. Now - when you remove a nick from your notify list, you no longer receive a spurious - signoff notification for that nick. Changed to make it IRC-case-insensitive when - comparing nicks. - - * erc.el(erc-ison-p): - Fixed so it calls erc-member-ignore-case instead of member. - - * erc.el(erc-member-ignore-case): - New function. Just like member-ignore-case, but obeys - the IRC protocol case matching rules. - -2003-01-10 Damien Elmes - - * erc-dcc.el: - (erc-dcc-do-GET-command), (erc-dcc-get-file): use the plist syntax, this - fixes dcc get again - -2003-01-10 Jorgen Schaefer - - * erc.el: erc-complete-functions: New variable. - erc-mode-map: Bind \t to 'erc-complete-word - erc-complete-word: New function. - - * erc-pcomplete.el(erc-pcomplete-mode): - Use new erc-complete-functions - (erc-pcomplete): Check that we're in the input line, else return nil. - - * erc-button.el(erc-button-mode): Use new erc-complete-functions - erc-button-old-tab-command: Removed. - (erc-button-next-or-old): Removed - (erc-button-next): check that we're not in the input line, else just return nil. - -2003-01-10 Mario Lang - - * erc-dcc.el: cleanup - - * erc-dcc.el: - * (erc-dcc-chat-request): No longer use erc-send-ctcp-message. - - * erc-dcc.el: - * (erc-dcc-no-such-nick): Also call delete-process if we have a peer already - - * erc-dcc.el: - * (erc-dcc-no-such-nick): New function, server event handler for event 401. - If we send a CTCP message requesting something dcc related, we set up an - entry in erc-dcc-list before sending the request (for the server proc object - for listening conns for example). But if that nick does not exist - on that server, we now nicely cleanup erc-dcc-list again. - -2003-01-09 Mario Lang - - * erc-dcc.el: Moved code around a bit, and doc fixes - - * erc-dcc.el: *** empty log message *** - - * erc-dcc.el: Rename erc-dcc-plist to erc-dcc-list - -2003-01-09 Damien Elmes - - * erc-dcc.el(erc-dcc-server (erc-dcc-chat-setup): - use erc's (erc-setup-buffer) to determine how to - display new DCC windows - (erc-dcc-chat-buffer-killed): buffer-local hook for DCC buffers to close the - process - (erc-dcc-chat-close): code common to a killed buffer or a disconnection from - the other side - (erc-dcc-chat-sentinel): use (erc-dcc-chat-close) - (erc-dcc-server-accept): use (erc-log) instead of (message) - - * erc.el: - (erc), (erc-setup-buffer): factor out window generation code so DCC can use - it too - - * erc-dcc.el: - (erc-dcc-do-CLOSE-command), (erc-dcc-do-LIST-command): work with erc-dcc-plist - - * erc-dcc.el: - erc-dcc-alist: became erc-dcc-plist, so we can more easily grab particular - properties - dcc catalog: unify use of DCC: and [dcc] (either's fine, but let's be - consistent) - (erc-dcc-member): takes an arbitrary list of constraints now - (erc-dcc-proc-member): removed, as (erc-dcc-member) can be used for this - (erc-dcc-do-CHAT-command): use the catalog to show the user what's going on - (erc-dcc-chat-server): removed - (erc-dcc-server): takes name sentinel and filter arguments, can be used for - both send and chat now - - .. this release means all send/get support is broken until we fix up the - things that still expect to be using an alist. this include /dcc list, /dcc - close - -2003-01-09 Francis Litterio - - * erc-ring.el(erc-previous-command): - If you have a partially typed input line and press M-p, - you lose what you typed. Now we save it so you can come back to it. - -2003-01-09 Jorgen Schaefer - - * erc-ring.el(erc-add-to-input-ring): s/nullp/null/ - -2003-01-09 Damien Elmes - - * erc-ring.el(erc-add-to-input-ring): - set up the ring if it's not already setup - - * erc-dcc.el(erc-dcc-member): case insensitive match of nicknames - (erc-dcc-do-CHAT-command): echo what we're doing (at least for now) - -2003-01-09 Mario Lang - - * erc-dcc.el: (temporarily) fix erc-process setting... - - * erc-dcc.el: * (erc-dcc-chat-send-line): Removed - - * erc.el: - Check if target is stringp (we can now also have 'dcc as value...) - - * erc-dcc.el(erc-dcc-chat-send-input-line): - New function, used for - erc-send-input-line-function. - Use erc-send-current-line now. - - * erc-dcc.el: evt to elt... - - * erc-dcc.el: Remove () from a var (how silly!) - - * erc-dcc.el: * (erc-dcc-get-host): Use format-network-address. - * (erc-dcc-host): Change semantic. If erc-dcc-host is set, use it. - Otherwise, try to figure out the host by calling erc-dcc-get-host. - * (erc-dcc-server-port): New variable. - * erc-dcc-chat-log: Renamed to erc-dcc-server-accept - - * erc-dcc.el(erc-dcc-do-CHAT-command): - Change arg of call to erc-dcc-chat-request from elt to nick - -2003-01-09 Francis Litterio - - * erc.el(erc-send-current-line): - Now rejects multi-line commands (i.e., lines that - start with "/" and contain newlines). - -2003-01-09 Jorgen Schaefer - - * erc-button.el: - Functionality to use TAB to jump to the next button: - - (erc-button-next-or-old): New function. - (erc-button-next): New function. - erc-button-keymap: added erc-button-next - erc-button-old-tab-command: New variable. - define-erc-module button: Add and remove 'erc-button-next-or-old as - appropriate. - -2003-01-09 Francis Litterio - - * erc.el: - New variable: erc-auto-reconnect (defaults to t). If non-nil, ERC will - automatically reconnect to a server after an unexpected disconnection. - (erc-process-sentinel): Changed to refer to variable erc-auto-reconnect. - -2003-01-08 Mario Lang - - * erc.el: - * erc-send-input-line-function: New variable, used for dispatch... - -2003-01-08 Damien Elmes - - * erc-dcc.el(erc-dcc-chat-sentinel): - check event type before killing process - (erc-dcc-chat-log): new, handles the setup of dcc chats for incoming - connections - (erc-dcc-chat): use (erc-dcc-chat-setup) - (erc-dcc-chat-setup): code common to incoming and outgoing DCC chats - (erc-dcc-chat-request): request a DCC chat with another user - (erc-dcc-proc-member): locate a member in erc-dcc-alist by process - - The very first ERC to ERC DCC chat was held between delysid and resolve today! - -2003-01-08 Mario Lang - - * erc-track.el(erc-all-buffer-names): - Check for erc-dcc-chat-mode too - -2003-01-08 Francis Litterio - - * erc-ring.el, erc.el(erc-kill-input): - Resets erc-input-ring-index to nil, so that invoking this - command conceptually puts you after your most recent input in the input - history. - (erc-previous-command and erc-next-command): Changed so that history movement - is more intuitive. Also preserves the blank input line that marks the - place after the newest command in the history ring (i.e., you'll see a - blank command once every trip around the ring in either direction). - -2003-01-08 Mario Lang - - * erc-dcc.el(erc-dcc-chat): Add docstring - Add self-test. - Fix error if /dcc chat nick doesn't find the nick - -2003-01-08 Francis Litterio - - * Makefile: - Changed so that "make" works correctly under Cygwin. Before this change, the - pathname passed to Emacs on the command line under Cygwin had the form - "/cygwin/c/...", which prevented emacs from finding the file. Now the pathname - has the form "c:/...". This works for any drive letter. - -2003-01-08 Mario Lang - - * erc-button.el: reindent some code, and add TODO to comments - - * erc-dcc.el: *** empty log message *** - - * erc-dcc.el: Make dcc-chat-ended a notice - Remove now bogus comment - -2003-01-08 Damien Elmes - - * erc-dcc.el(erc-pack-int): from erc-packed-int - (erc-unpack-int): new - - * erc-dcc.el(erc-unpack-str): added - -2003-01-08 Mario Lang - - * erc.el(erc-server-482): - New handler, handles KICK reply if you're not channel-op - - * erc-dcc.el: Document SEND in erc-dcc-alist. - Move sproc, parent-proc and file into erc-dcc-alist - - * erc-dcc.el: stubs - - * erc-dcc.el(erc-dcc-get-host): - Change :iface to :local since Kim committed it now to CVS emacs - - * erc-dcc.el(erc-dcc-get-host): - New function, requires the not-yet-in-CVS-emacs local-address.patch to process.c. - Some other minor additions - -2003-01-08 Francis Litterio - - * erc.el(erc-cmd-IGNORE): - Now returns t to prevent "Bad syntax" error. - (erc-cmd-UNIGNORE): Now returns t to prevent "Bad syntax" error. - (erc-server-PRIVMSG-or-NOTICE): Capitalized first word in message to user. - - * erc.el(erc-scroll-to-bottom): - 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. - -2003-01-07 Jorgen Schaefer - - * erc-dcc.el: - erc-dcc-ctcp-query-chat-regexp: The IP is not really an IP, but a - number (no . allowed there). - (erc-dcc-send-ctcp-string): use let* here to avoid cluttering up the - match data. - Also, use erc-decimal-to-ip to get the IP. - (erc-ip-to-decimal): Removed some pasted ERC timestamps - (erc-decimal-to-ip): New function. - erc-dcc-chat-mode-map: Return map in the initialization. - -2003-01-07 Francis Litterio - - * erc-match.el(erc-match-fool-p): - Changed to call erc-match-directed-at-fool-p instead of - erc-directed-at-fool-p. - -2003-01-07 Mario Lang - - * erc-dcc.el(erc-cmd-DCC): - Change (cond ... (t nil)) to (when ...) - - * erc-dcc.el: Use erc-current-nick-p - -2003-01-07 Jorgen Schaefer - - * erc.el: - erc-join-buffer: Added 'window-noselect to docstring and :type. - erc-auto-query: Added 'window-noselect to :type. - (erc): Treat erc-join-buffer being 'window-noselect appropriately. - - * erc.el(erc-current-nick-p): New function. - (erc-nick-equal-p): New function. - (erc-already-logged-in), (erc-server-JOIN), (erc-auto-query), - (erc-server-PRIVMSG-or-NOTICE): Use erc-current-nick-p. - (erc-update-channel-member): Use erc-nick-equal-p. - - * erc-match.el(erc-match-current-nick-p): - Renamed from erc-current-nick-p - (erc-match-pal-p): Renamed from erc-pal-p - (erc-match-fool-p): Renamed from erc-fool-p - (erc-match-keyword-p): Renamed from erc-keyword-p - (erc-match-dangerous-host-p): Renamed from erc-dangerous-host-p - (erc-match-directed-at-fool-p): Renamed from erc-directed-at-fool-p - (erc-match-message): Use erc-match-TYPE-p instead of erc-TYPE-p - - * erc.el: - Support for IRCnets' "nick/channel temporarily unavailable" - - (erc-nickname-in-use): New function (mostly copied from erc-server-433). - (erc-server-433): Use erc-nickname-in-use - (erc-server-437): New function. - erc-server-hook-list: Added (437 erc-server-437). - -2003-01-07 Mario Lang - - * erc-fill.el: Add autoload cookie - - * erc-notify.el: - Now also pass SERVER argument to signon/off hooks, and provide a erc-notify-signon/off function for echo-area printing - - * erc-notify.el(erc-notiy-QUIT): - Change use of delq to delete, delq does not work with strings - -2003-01-06 Jorgen Schaefer - - * erc.el(erc-ctcp-query-VERSION): - v%s -> %s, so we are no longer vVersion... - -2003-01-06 Mario Lang - - * erc.el: Small change to erc-ison-p, and fixme tag - -2003-01-06 Francis Litterio - - * erc.el(erc): - Fixed bug where variable "away" would be nil in new channel buffers - even if the user is away when joining the channel. - (erc-strip-controls): Fixed a bug where erc-strip-controls accidentally - removed all text properties from the string. - -2003-01-06 Mario Lang - - * erc-dcc.el: - Some stub functions, some code, nothing really works yet - - * erc.el(erc-ison-p): New function - - * erc-dcc.el: Some functions which will be needed for dcc send - - * erc-dcc.el(erc-ip-address-to-decimal): - New function, thanks lawrence - - * erc-dcc.el: Again, simplify code, fix stuff, DCC CHAT works now - - * erc-dcc.el: Many fixes, chat nearly works now - - * erc-netsplit.el: Also detect fast netsplit/joins - - * erc-dcc.el: some more fixes - - * erc-dcc.el: Fixup stage 1, now dcc get works - - * erc-dcc.el: make /dcc LIST work - - * erc-dcc.el: - Initial checkin, don't use it! its really far from complete. Hackers: help! - - * erc-notify.el: - New function erc-notify-NICK, and added signon/off hooks which were missing - -2003-01-05 Jorgen Schaefer - - * erc.el(erc-truncate-buffer-to-size): - set inhibit-read-only to t for the - deletion. This is usually done by the function calling the hook, but - not if it's called interactively. Also, rewrote some weird if/if - combination. - - * erc-track.el(erc-track-shortennames): - Documentation fix (erc-all-buffers is really - erc-all-buffer-names) - - These changes make server buffers be tracked as well, as there are - quite a few interesting things going on there (e.g. CTCP etc.) - (erc-all-buffer-names): Check for (eq major-mode 'erc-mode) instead of - erc-default-recipients. - (erc-track-modified-channels): Don't require a default target (e.g., - this-channel being non-nil) - -2003-01-03 Damien Elmes - - * erc.el: - erc-auto-query: can now be set to a symbol to control how new messages should - be popped up (or not popped up, as the case may be) - (erc-query): new function which handles the bulk of what (erc-cmd-QUERY) did - previously - (erc-cmd-QUERY): use (erc-query) - (erc-auto-query): use (erc-query) - - * erc.el(erc-current-logfile): - Downcase result of log generation function, as IRC is - case insensitive. Fixes problems where "/query user" results in a different - log file to a query from "User". Avoided adding an extra flag to control this - behavior - if you think this was the wrong decision, please correct it and - I'll remember it for next time. - -2002-12-31 Francis Litterio - - * erc.el(erc-split-command): - Removed assignment to free variable "continue". - (erc-strip-controls): New function. Takes a string, returns the string with - all IRC color/bold/underline/etc. control codes stripped out. - (erc-interpret-controls): If variable erc-interpret-controls-p is nil, now - uses erc-strip-controls to strip control codes. - (erc-ctcp-reply-ECHO): Changed reference and assignment to free variable "s" - into reference/assignment to "msg", which appears to be the original author's - intent. - - * erc-list.el(erc-chanlist): - Changed to use the new erc-once-with-server-event function - instead of the old macro of the same name. - - * erc-notify.el(erc-notify-timer): - Changed to use the new erc-once-with-server-event function - instead of the old macro of the same name. Also fixed a bug were variable - erc-last-ison was being read from a non-server buffer (thus giving its default - value instead of its per-server value). - - * erc.el(erc-once-with-server-event): - This is now a function. It was a macro with a - bug (the call to gensym happened at byte-compile-time not macro-call-time). - (erc-toggle-debug-irc-protocol): Now [return] is bound to this function in - the *erc-protocol* buffer. - -2002-12-30 Alex Schroeder - - * erc-autoaway.el(erc-autoaway-idletimer): Doc, - ref. erc-autoaway-use-emacs-idle. - (autoaway): Doc, explain different idle definitions. Reestablish - the idletimer only when erc-autoaway-use-emacs-idle is non-nil. - (erc-auto-set-away): Doc, ref erc-auto-discard-away. - (erc-auto-discard-away): Doc, ref erc-auto-set-away. - (erc-autoaway-use-emacs-idle): Doc, ref erc-autoaway-mode, and - added a note that this feature is currently broken. - (erc-autoaway-reestablish-idletimer): Doc. - (erc-autoaway-possibly-set-away): Split test such that - erc-time-diff is only computed when necessary, add a comment why - erc-process-alive is not necessary. - (erc-autoaway-set-away): Test for erc-process-alive. - -2002-12-29 Alex Schroeder - - * erc-autoaway.el: - Changed the order of defcustoms to avoid errors in the :set property - of erc-autoaway-idle-seconds. - -2002-12-29 Damien Elmes - - * erc-track.el: - * (erc-track-get-active-buffer): remove superfluous (+ arg 0) - -2002-12-29 Alex Schroeder - - * erc-autoaway.el(erc-autoaway): Moved the defgroup up to the - top, before the define-erc-module call. - (autoaway): Extended doc. - (erc-autoaway-idle-seconds): Use a :set property to handle - erc-autoaway-use-emacs-idle. - (erc-auto-set-away): Set default to t. Added doc strings where - necessary, reformatted doc strings such that the first line can - stand on its own. This is important for the output of M-x - apropos. - -2002-12-28 Jorgen Schaefer - - * erc-auto.in: - added (provide 'erc-auto), which is required for (require 'erc-auto) :) - - * erc.el(erc-display-prompt): - Set the face property of the prompt to - everything but the last character. - - * erc.el(erc-send-current-line): - Check whether point is in the input line. If - not, just beep and do nothing. - -2002-12-28 Alex Schroeder - - * erc.el(erc-bol): - Fixed bug when there is only a prompt, and no property - change. - - * erc.el(erc-display-prompt): Rewrote using a save-excursion - and erc-propertize. No longer use a field for the prompt, but a - plain text property called erc-prompt. - (erc-bol): Use the erc-prompt text property instead of a field. - Return point instead of t. - (erc-parse-current-line): No need to call point here, then, since - erc-bol now returns point. - - * Makefile: - make ChangeLog .PHONY, thus forcing it always to be rebuilt. - -2002-12-28 Jorgen Schaefer - - * erc.el(erc-log-irc-protocol): - Removed check whether get-buffer-create - returned nil. "The value is never nil", says the docstring. - - * erc.el: Day Of The Small Changes - - (erc-display-prompt): Make the prompt 'front-sticky, which prevents it - from being modified. It *should* also make end-of-line move to the - end of the field (i.e. the end of the prompt) when point is at the - beginning of the prompt, but it doesn't. Dunno why. :( - -2002-12-27 Francis Litterio - - * Makefile: - Added "-f" to "rm" command in rule for target "realclean". - - * erc.el: - New function: erc-log-irc-protocol. Consolidates nearly duplicate code - from functions erc-send-command and erc-process-filter into one function. - - * erc.el(erc-toggle-debug-irc-protocol): - Removed unneeded argument PREFIX and code - which referenced it at end of function. - (erc-send-command): Now we only append a newline to the logged copy - of output protocol text if it doesn't have one. - -2002-12-27 Jorgen Schaefer - - * erc.el(erc-toggle-debug-irc-protocol): - Display buffer if it's not shown - already, and use view-mode. - (erc-toggle-debug-irc-protocol), (erc-send-command), - (erc-process-filter): inhibit-only t to insert into the - *erc-protocol* buffer (view-mode) - -2002-12-27 Francis Litterio - - * erc.el(erc-mode-map): - Removed keybinding for erc-toggle-debug-irc-protocol. - (erc-toggle-debug-irc-protocol): Now used erc-make-notice to propertize the - face of the enabled/disabled messages in the *erc-protocol* buffer. - (erc-send-command): Now outgoing IRC protocol traffic is logged too. - - * erc.el: - Added user-customizable variable erc-debug-irc-protocol. - Added function erc-toggle-debug-irc-protocol. - (erc-process-filter): Now supports IRC protocol logging. If variable - erc-debug-irc-protocol is non-nil, all IRC protocol traffic is appended - to buffer *erc-protocol*, which is created if necessary. - -2002-12-27 Jorgen Schaefer - - * erc.el(erc-display-prompt): - Don't make the prompt intangible; that didn't - make things that much better for the user, but confused ispell, - which checked the prompt when it should check the first word - -2002-12-27 Alex Schroeder - - * AUTHORS: fixed resolve's email add - - * AUTHORS: added damien - - * erc.el(erc-truncate-buffer-on-save): - Removed documentation that - described behavior now changed. It used to say "When nil, no - buffer is ever truncated." This is no longer true; even when - buffers are NOT truncated on save, they can be truncated, eg. by - adding erc-truncate-buffer to the hook. - (erc-logging-enabled): New function. - (erc-current-logfile): New function. - (erc): Use erc-logging-enabled and erc-current-logfile. - (erc-truncate-buffer-to-size): Rewrote it, and made sure to use a - (save-restriction (widen) ...) such that the truncation actually - runs in the whole buffer, not in the last message only (as - erc-insert-post-hook will do!). This should fix rw's - out-of-bounds error. - (erc-generate-log-file-name-short): Made all but the BUFFER - argument optional. Doc: Mention - erc-generate-log-file-name-function. - (erc-generate-log-file-name-long): Doc: Mention - erc-generate-log-file-name-function. - (erc-save-buffer-in-logs): Use erc-logging-enabled and - erc-current-logfile. Doc: Mention erc-logging-enabled. - - (erc-encode-string-for-target): Only do the real work when - featurep mule; else just return the string unchanged. - -2002-12-27 Damien Elmes - - * erc.el: - erc-encoding-default: check for (coding-system-p) for older emacs versions - - * erc.el(erc-connect): missing ()s added. "don't commit at 2am" - - * erc.el(erc-connect): - check if (set-process-coding-system) is available before use - -2002-12-27 Alex Schroeder - - * AUTHORS: added franl - -2002-12-26 Alex Schroeder - - * erc-pcomplete.el(pcomplete-parse-erc-arguments): - Reworked, and fixed a bug that had - caused completions to corrupt preceding text under some circumstances. - - * erc.el(erc-encoding-default): New. - (erc-encode-string-for-target): Use it instead of a hard-coded ctext. - (erc-encoding-coding-alist): Doc. - -2002-12-26 Francis Litterio - - * erc.el: - Removed fix for bug 658552 recently checked-in, because it doesn't work. - - * erc.el(erc-kill-buffer-function): - Removed check that connection is up - before running erc-kill-server-hook hooks. Those hooks should use - erc-process-alive to avoid interacting with the process. - - * erc.el: - Fixed erc-send-current-line so it no longer assigns the free variable "s", and - it doesn't move point to end-of-buffer in non-ERC buffers. Fixed - erc-kill-buffer-function so it doesn't run the erc-kill-server-hook hooks if the - server connection is closed. Fixed bug 658552, which is described in detail at - https://sourceforge.net/tracker/index.php?func=detail&aid=658552&group_id=30118&atid=398125 - -2002-12-26 Alex Schroeder - - * erc.el(erc-cmd-SMV): Bug, now call erc-version-modules. - - * erc-pcomplete.el(erc-pcomplete-version): New. - -2002-12-26 Francis Litterio - - * erc-pcomplete.el: - Fix for bug where you could not complete a nick when there was text following - the nick. - -2002-12-25 Alex Schroeder - - * erc.el(erc-already-logged-in): Use erc-process-alive. - (erc-prepare-mode-line-format): Use erc-process-alive. - (erc-process-alive): Check erc-process for boundp and processp. - - * erc.el(erc-kill-buffer-function): - Do not check whether the process is - alive before running the hook, because there might be functions on - the hook that need to run even when the process is dead. And - function that wants to check this, should use (erc-process-alive). - (erc-process-alive): New function. - (erc-kill-server): Use it. - (erc-kill-channel): Use it. - - * erc.el(erc-kill-buffer-function): - Reverted ignore-error change. - ignore-error is dangerous because we might miss bugs in functions - on erc-kill-server-hook. - - * erc.el(erc-kill-buffer-function): Use memq instead of member - when checking process-status. Added doc string with references to - the other hooks. - (erc-kill-server): Only send the command when the erc-process is - still alive. This prevents the error: "Process - erc-irc.openprojects.net-6667 not running" when killing the buffer - after having used /QUIT. - -2002-12-24 Jorgen Schaefer - - * erc.el(erc-server-ERROR): - Show the error reason, not only the originating host. - - * erc.el(erc-kill-buffer-function): - (ignore-errors ...) in 'erc-kill-server-hook. - When the process for this server does not exist anymore, the hook - will cause an error, effectively preventing the buffer from being - killed. - -2002-12-24 Francis Litterio - - * erc-notify.el: - Fixed erc-notify-timer so that it passes the correct nick to - the functions on erc-notify-signoff-hook. - -2002-12-24 Alex Schroeder - - * erc-track.el: Doc - - * erc-track.el(erc-make-mode-line-buffer-name): Removed a - superfluous if construct around erc-track-showcount-string. - (erc-track-modified-channels): Use 1+. - Plus some doc and comment changes. - -2002-12-23 Mario Lang - - * erc.el: Fix (erc-version) string - -2002-12-23 Francis Litterio - - * erc.el: - Removed unnecessary assignment to free-variable "p" in erc-downcase. - - * erc.el: - Now /PART reason strings are generated the same way /QUIT reason strings - are generated (see variable erc-part-reason). Also, when a server buffer - is killed, a QUIT command is automatically sent to the server. - - * erc.el: - Changed erc-string-no-properties so that it is more efficient. Now it uses - set-text-properties instead of creating and deleting a temporary buffer. - -2002-12-21 Jorgen Schaefer - - * erc.el: - erc-kill-input: added a check to prevent a (ding) and an error when - there's nothing to kill (thanks to Francis Litterio, franl on IRC) - -2002-12-21 Mario Lang - - * erc.el: - AWAY notice duplication prevention. erc-prevent-duplicates now set to ("301") by default, and timeout to 60 - - * erc.el: erc-prevent-duplicates: New variable, see docstring - -2002-12-20 Jorgen Schaefer - - * erc-track.el: - erc-track-modified-channels: Use cddr of cell for old-face. cdr of - cell is '(1 . face-name), i have no idea why :) - -2002-12-20 Damien Elmes - - * erc.el(erc-current-nick): - check the server buffer is active before using - - Also tabified and cleaned up some trailing whitespace - -2002-12-15 Mario Lang - - * erc-track.el: erc-track-count patch by az - -2002-12-14 Damien Elmes - - * erc.el: - last-peers: initialize to a cons. thanks to Francis Litterio - for the patch - - * erc.el: - erc-kill-channel-hook, erc-kill-buffer-hook, (erc-kill-channel): - both hooks now call erc-save-buffer-in-logs, so that query buffers are - saved properly now, and not just channel buffers. - -2002-12-13 Alex Schroeder - - * erc-track.el(erc-unique-channel-names): Fix another #hurd - vs. #hurd-bunny bug. - - * erc-match.el(match): No longer modify erc-send-modify-hook, - since it does not work without a parsed text property, anyway. - (erc-keywords): Allow cons cells. - (erc-remove-entry-from-list): Deal with cons cells. - (erc-keyword-p): Ditto. - (erc-match-message): Ditto. - - Moved nil to the beginning of the list, removed :tags for the - -type variables: - (erc-current-nick-highlight-type): Ditto. - (erc-pal-highlight-type): Ditto. - (erc-fool-highlight-type): Ditto. - (erc-keyword-highlight-type): Ditto. - (erc-dangerous-host-highlight-type): Ditto. - (erc-log-matches-flag): Moved nil to the beginning. - -2002-12-11 Jorgen Schaefer - - * erc.el: - erc-beg-of-input-line: Don't do (goto-char (beginning-of-line)), since - beginning-of-line always moves point and returns nil. Thanks to - franl on IRC for noting this. - - * erc-stamp.el: - erc-insert-timestamp-left, erc-insert-timestamp-right: Made the - timestamp a 'field named 'erc-timestamp. Now end-of-line and - beginning-of-line will move over the timestamp. - -2002-12-10 Damien Elmes - - * erc-button.el(erc-button-add-button): - make the created button rear-nonsticky, to allow - cutting and pasting of buttons without worrying about the button properties - being inherited by the text typed afterwards. - - * erc.el: save logfile when killing buffer - -2002-12-09 Alex Schroeder - - * erc-track.el(erc-modified-channels-display): Reworked. - (erc-track-face-more-important-p): Removed. - (erc-track-find-face): Return only one face. - (erc-track-modified-channels): Reworked. - (erc-modified-channels-string): Changed from (BUFFER FACE...) to - (BUFFER . FACE) - - * erc-stamp.el(erc-insert-timestamp-right): Do not assume - erc-fill-column is available. - -2002-12-09 Jorgen Schaefer - - * erc.el: - erc-ech-notices-in-minibuffer-flag, erc-minibuffer-notice: Clarified - the difference in the docstrings. - -2002-12-08 Jorgen Schaefer - - * erc.el: erc-noncommands-list: added erc-cmd-SM and erc-cmd-SMV - -2002-12-08 Alex Schroeder - - * erc.el(erc-cmd-SM): New. - (erc-cmd-SMV): New. - - * erc.el(erc-modes): New. - -2002-12-08 Jorgen Schaefer - - * erc-compat.el: - field-end: use (not (fboundp 'field-end)) instead of (featurep 'xemacs) - -2002-12-08 Alex Schroeder - - * erc.el(erc-version-modules): New. - -2002-12-08 Mario Lang - - * debian/changelog, debian/control, debian/scripts/startup.erc: - debian release 3.0.cvs.20021208 - -2002-12-08 Jorgen Schaefer - - * erc.el(erc-split-command): Do the right thing with CTCPs. - -2002-12-08 Mario Lang - - * erc-stamp.el: Be a bit more functional - -2002-12-08 Jorgen Schaefer - - * erc-compat.el: - XEmacs doesn't seem to have field-end, so we provide our own version here. - -2002-12-08 Mario Lang - - * Makefile: Small fixes to debrelease target - -2002-12-08 Jorgen Schaefer - - * erc.el: - make-obsolete-variable: xemacs doesn't have the WHEN parameter, remove it. - -2002-12-07 Jorgen Schaefer - - * erc-imenu.el(erc-create-imenu-index): - Use (forward-line 0) instead of - (beginning-of-line) now, sine the latter ignores fields (used in the - prompt). - - * erc.el: - Rewrite of the prompt stuff to use a field named 'erc-prompt: - - erc-prompt: Removed getter and setter functions. The properties were - already set (and overwritten) in erc-display-prompt. - (erc-prompt): Add the trailing space here, not all over the code. - (erc-display-prompt): Cleaned up a bit. The text-properties now are - valid on the whole prompt. Also, made the prompt 'intangible to - avoid confused users. - (erc-bol): Now use the field 'erc-prompt for finding the prompt - (erc-parse-current-line): Cleaned up considerably. Uses (erc-bol) now. - (erc-load-irc-script-lines): Adjusted for the new (erc-prompt). - (erc-save-buffer-in-logs): Adjusted for the new (erc-prompt). - - * erc.el: - erc-uncontrol-input-line: The comment said "Consider it deprecated", - so I removed it now. - erc-prompt-interactive-input: Marked obsolete as of previous change. - - * erc.el: - erc-smiley, erc-unmorse: Put at the end to separate it from the - important parts of erc.el. - -2002-12-07 Alex Schroeder - - * erc-stamp.el(erc-insert-timestamp-right): New algorithm. - -2002-12-07 Jorgen Schaefer - - * erc.el: - last-peers, erc-message: Explained what last-peers is used for. - -2002-12-07 Alex Schroeder - - * erc-page.el(erc-cmd-PAGE): New function. - (erc-ctcp-query-PAGE): Use the catalog entry for the message, too. - (erc-ctcp-query-PAGE-hook): Added custom type. - (erc-page-function): Changed custom type from ... function-item to - ... function. - As well as doc strings. - -2002-12-06 Alex Schroeder - - * erc-page.el: provide feature at the end - -2002-12-06 Brian P Templeton - - * erc-nickserv.el: - Added austnet in erc-nickserv.el (thanks to Damien Elmes - ) - -2002-12-05 Mario Lang - - * erc-complete.el: Add autoload cookie - - * erc-speak.el: Small fix to make proper voice-changes - -2002-12-05 Alex Schroeder - - * erc-lang.el: New - -2002-12-03 Jorgen Schaefer - - * erc.el: - erc-mode-map: Put back C-c C-p (PART) and C-c C-q (QUIT) - -2002-12-02 Jorgen Schaefer - - * erc.el: - erc-insert-post-hook: Add :options erc-make-read-only, erc-save-buffer-in-logs - erc-send-post-hook: Add :options erc-make-read-only - - * erc.el: erc-insert-hook: Removed ("this hook is obsolescent") - erc-insert-post-hook: Added :options '(erc-truncate-buffer) - -2002-12-02 Mario Lang - - * erc.el: Add missing requires - -2002-11-29 Jorgen Schaefer - - * erc.el(erc-quit-reason-normal): - Remove v before %s so it's "Version ..." not - "vVersion ..." - -2002-11-26 Alex Schroeder - - * erc-compat.el(erc-encode-coding-string): Add second argument - coding-system, and for non-mule xemacsen, use a new defun instead - of identity. - - * erc.el: (define-erc-module): Use the appropriate group. - (erc-port): Changed custom type. - (erc-insert-hook): Custom group changed to erc-hooks. - (erc-after-connect): ditto - (erc-before-connect): ditto - (erc-disconnected-hook): ditto - - * erc-button.el(erc-button): New group, changed all custom groups - from erc to erc-button, but left all erc-faces as-is. - - * erc-track.el(erc-track): New group, changed all custom groups - from erc to erc-track. - -2002-11-26 Mario Lang - - * erc-macs.el: - Macros for erc-victim handling. Primary idea is to use setf and some fancy things to get nice syntax. have a look - -2002-11-26 Jorgen Schaefer - - * erc.el: - pings, erc-cmd-PING, erc-ctcp-reply-PING, catalog entry CTCP-PING: - Cleaned up. Removed buffer-local variable pings which stored a list of - all sent CTCP PING requests. Now send our full time with the CTCP PING - request and interpret the answer. - -2002-11-25 Jorgen Schaefer - - * erc.el: nick-stk: replaced by the local variable current-nick. - -2002-11-25 Alex Schroeder - - * erc.el(erc-send-command): Use erc-encode-string-for-target. - (erc-encode-string-for-target): New. - - * erc-compat.el(erc-encode-coding-string): Add second argument - coding-system, and for non-mule xemacsen, use a new defun instead - of identity. - - * erc-nickserv.el(erc-nickserv-version): New. - -2002-11-25 Jorgen Schaefer - - * Makefile: - UNCOMPILED: erc-chess.el depends on chess-network.el, which might not - be installed. Don't compile it. - - * erc.el: - erc-mode-map: Added C-a as erc-bol (no reason why it shouldn't be), - and removed C-c C-p (part channel) and C-c C-q (quite server) as these - are a bit drastic in their consequences and easy to mistype. - -2002-11-24 Jorgen Schaefer - - * erc-track.el: erc-track-faces-priority-list: Extended list - - * erc.el: - channel-members: Updated docstring: We have a VOICE predicate, too. - - * erc-track.el(erc-unique-substrings): - Don't shorten a single channel to "#", but - always give at least 2 chars (except when there are no two chars). - -2002-11-23 Jorgen Schaefer - - * erc-nickserv.el: - support for BrasNET. Thanks to rw on IRC for the settings. - -2002-11-23 Alex Schroeder - - * erc.el: (erc-default-recipients, erc-session-user-full-name) - (nick-stk, pings, erc-announced-server-name, erc-connected) - (channel-user-limit, last-peers, invitation, away, channel-list) - (last-sent-time, last-ping-time, last-ctcp-time, erc-lines-sent) - (erc-bytes-sent, quitting, bad-nick, erc-logged-in) - (erc-default-nicks): Defvars. - - * erc-compat.el: Switched tests to iso-8859-1 instead of latin-1. - - * erc-compat.el(erc-compat-version): New. - -2002-11-22 Alex Schroeder - - * erc.el(smiley): Smileys are a very small module, now. - -2002-11-22 Jorgen Schaefer - - * erc.el: - erc-event-to-hook, erc-event-to-hook-name: eval-and-compile these, - since we need them in a macro. ERC now compiles again! - - * erc-speak.el: - erc-minibuffer-privmsg: Removed setting this variable to nil, since it - was removed from erc.el. - - * erc.el(erc-interactive-input-map): Added docstring. - (erc-wash-quit-reason): Extended docstring. - (erc-server-ERROR): Added docstring. - (erc-server-321): buffer-local variable channel-list probably - shouldn't be renamed erc-channel-list - removed FIXME. - - * erc.el: small cleanup. - ("was not used anymore" here means "not used in erc/*.el nor in - fsbot", thanks to deego for checking that.) - - erc-minibuffer-privmsg: Removed (was not used anymore) - (erc-reformat-command): Removed (was not used anymore) - (erc-strip-erc-parsed-property): Removed (was not used anymore) - (erc-process-ctcp-response): Removed (replaced by ctcp-query-XXX-hook) - (erc-send-paragraph): Removed ("Note that this function is obsolete, - erc-send-current-line handles multiline input.") - (erc-input-hook): Removed ("This hook is obsolete. See - `erc-send-pre-hook', `erc-send-modify-hook' and - `erc-send-post-hook' instead.") - (erc-message-hook): Removed ("This hook is obsolete. See - `erc-server-PRIVMSG-hook' and `erc-server-NOTICE-hook'.") - (erc-cmd-default-channel): Removed ("FIXME: no clue what this is - supposed to do." - it was supposed to prepend the default channel - to a command before sending it. E.g. typing "/FOO now!" would send - the IRC command "FOO #mycurrentchannel now!") - - * erc.el: - erc-ctcp-query-PING: Send the whole argument back, not just the first - number. This is required for many clients (e.g. irssi, BitchX, ...) - which send their ping times in two different numbers for microsecond - accuracy. - -2002-11-22 Alex Schroeder - - * erc-track.el(erc-track-shorten-function): Allow nil. - -2002-11-21 Alex Schroeder - - * erc-track.el(erc-unique-channel-names): Fixed bug that appeared - if one target name was a substring of another -- eg. #hurd and - #hurd-bunny. Added appropriate test. - -2002-11-20 Jorgen Schaefer - - * erc-track.el: - erc-unique-channel-names: Don't take a substring of channel that could - be longer than the channel, but at most (min (length candidate) - (length channel). (thanks to deego for noticing this) - -2002-11-19 Mario Lang - - * erc-notify.el: * (require pcomplete): Only when compiling. - -2002-11-19 Jorgen Schaefer - - * erc-track.el: - erc-track-faces-priority-list: New variable, defines what faces will - be shown in the modeline. If set to nil, the old behavior ("all") - remains. - erc-track-face-more-important-p: new function - erc-track-find-face: new function - -2002-11-19 Alex Schroeder - - * erc-fill.el(erc-stamp): Require it. - - * erc-match.el(away): devar for the compiler. - - * erc-stamp.el(stamp): Moved. - - * erc.el(erc-version-string): New version. - - * erc-autoaway.el(erc-autoaway-idletimer): Moved to the front of - the file. - - * erc-auto.in: (generated-autoload-file, command-line-args-left): - Added defvar without value to silence byte compiler. - - * Makefile(realclean): renamed fullclean to realclean. - (UNCOMPILED): New list, for erc-bbdb.el, erc-ibuffer.el, - erc-speak.el. - (SOURCE): Do not compile UNCOMPILED. - (release): New target. - (ChangeLog): New target. - (todo): New target. - - * erc-complete.el(erc-match): Require it. - (hippie-exp): Require it. - - * erc-ezbounce.el(erc): Require it. - - * erc-imenu.el(imenu): Require it. - - * erc-nickserv.el(erc-networks): Moved up. - - * erc-notify.el(pcomplete): Require it. - - * erc-replace.el(erc): Require it. - - * erc-sound.el(sound): Typo -- define-key in erc-mode-map. - - * erc-speedbar.el(dframe): Require it. - (speedbar): Require it. - - * erc-track.el(erc-default-recipients): devar for the compiler. - - * README: New file. - -2002-11-18 Mario Lang - - * AUTHORS: File needed for mkChangeLog - - * mkChangeLog: Original code by mhp - -2002-11-18 Alex Schroeder - - * erc-button.el(erc-button-list): Renamed to erc-list and moved - to erc.el. - - * erc.el(erc-list): New. - - * erc-track.el(erc-make-mode-line-buffer-name): Simplified. - (erc-modified-channels-display): Simplified. Now works with all - faces, and fixes the bug that when two faces where used (bold - erc-current-nick-face), then no faces was added. - - * erc-track.el: Lots of new tests. Moved some defuns around in - the file. - (erc-all-channel-names): Renamed. - (erc-all-buffer-names): New name, now include query buffers as - well. - (erc-modified-channels-update-inside): New variable. - (erc-modified-channels-update): Use it to prevent running display - if already inside it. This prevented debugging of - `erc-modified-channels-display'. - (erc-make-mode-line-buffer-name): Moved. - (erc-track-shorten-names): Don't test using erc-channel-p as that - failed with query buffers. - (erc-unique-substrings): Move setq i + 1 to the end of the while - loop, so that start is used as a default value instead of start + - 1. - -2002-11-18 Jorgen Schaefer - - * erc-track.el: - erc-unique-substrings: define this before using it in assert - - * erc.el: - with-erc-channel-buffer: Define *before* using this macro. This - hopefully fixes a bug noted on IRC. - - * erc-notify.el: - erc-notify-signon-hook, erc-notify-signoff-hook: New hooks. They're - even run when their name suggests! - -2002-11-18 Alex Schroeder - - * erc-list.el: Typo. - - * erc-speedbar.el: Whitespace only. - - * erc.el(define-erc-module): Avoid defining an alias if name and - alias are the same. - - * erc-ibuffer.el: URL - - * erc-imenu.el(erc-imenu-version): New constant. - - * erc-ibuffer.el(erc-ibuffer-version): New constant. - - * erc-ibuffer.el: File header, comments. - - * erc-fill.el(erc-fill-version): New constant. - - * erc-ezbounce.el(erc-ezb-version): New constant. - - * erc-complete.el(erc-complete-version): New constant. - - * erc-chess.el(erc-chess-version): New constant. - - * erc-chess.el: Whitespace only. - - * erc-bbdb.el(erc-bbdb-version): Typo. - - * erc-bbdb.el(erc-bbdb-version): New constant. - Lots of whitespace changes. Changes to the header. - - * erc-track.el(erc-track-shorten-aggressively): Doc. - (erc-all-channel-names): New function. - (erc-unique-channel-names): New function. - (unique-substrings): Renamed. - (erc-unique-substrings): New name - (unique-substrings-1): Renamed. - (erc-unique-substring-1): New name. Added lots of tests. - (erc-track-shorten-names): Call erc-unique-channel-names instead - - * erc-match.el(match): Rewrote a as module. - -2002-11-17 Alex Schroeder - - * erc-netsplit.el(erc-netsplit-version): New. - (netsplit): Defined as a module, replacing erc-netsplit-initialize - and erc-netsplit-destroy. - -2002-11-17 Jorgen Schaefer - - * erc-track.el(erc-track-switch-buffer): - define-erc-module defines erc-track-mode, - not erc-track-modified-channels-mode. - - * erc.el: - Variables erc-play-sound, erc-sound-path, erc-default-sound, - erc-play-command, erc-ctcp-query-SOUND-hook and functions - erc-cmd-SOUND, erc-ctcp-query-SOUND, erc-play-sound, erc-toggle-sound - moved to erc-sound.el - - Variables erc-page-function, erc-ctcp-query-PAGE-hook and function - erc-ctcp-query-PAGE moved to erc-page.el - - * erc-page.el: - erc-page.el: New file. CTCP PAGE support for ERC, extracted from erc.el. - - * erc-sound.el: - defin-erc-module: Typo. Autoload should do erc-sound-mode and "erc-sound". - - * erc-sound.el: - erc-sound.el: New file. Contains all the CTCP SOUND stuff from erc.el. - - * erc.el(erc-process-ctcp-request): - Removed (old-style CTCP handling) - (erc-join-autogreet): Removed (was broken anyways) - -2002-11-17 Alex Schroeder - - * erc-button.el(erc-button-version): New constant. - - * erc-button.el(button): rewrote as a module. - -2002-11-17 Jorgen Schaefer - - * erc.el: New functions: - (erc-event-to-hook), (erc-event-to-hook-name): Convert an event to the - corresponding hook. The latter only returns the name, while the former - interns the hook symbol and returns it. - -2002-11-17 Alex Schroeder - - * erc-replace.el: - Practically total rewrite. All smiley stuff deleted. - - * erc-track.el(track): typo. - - * erc.el(define-erc-module): Doc change. - -2002-11-17 Jorgen Schaefer - - * erc-autoaway.el: Changed to use define-erc-module. - - * erc.el(define-erc-module): - Make the enable/disable functions interactive. - - * erc.el(erc): - Don't use switch-to-buffer when we're in the minibuffer, - because that does not work. Use display-buffer instead. This leaves - two problems: The point does not advance to the end of the buffer for - whatever reason, and after leaving the minibuffer, the new window gets - buried. - -2002-11-17 Alex Schroeder - - * erc-stamp.el(stamp): Doc change. - - * erc-stamp.el(erc-stamp-version): New constant. - (stamp): downcase alias name of the mode. - - * erc.el(define-erc-module): Added defalias option, renamed - parameters again. - - * erc-track.el: erc-track-modified-channels-mode is now only an - alias to erc-track-mode. Only erc-track-mode is autoloaded. - (track): Rewrote call to define-erc-module. - -2002-11-16 Mario Lang - - * debian/README.Debian: * Spelling fix - - * erc-fill.el: * Fix autoload definition for erc-fill-mode - - * debian/control, debian/maint/postinst, debian/maint/prerm: - * Remove /usr/doc -> /usr/share/doc link handling - - * debian/changelog: * Sync with reality - - * debian/scripts/startup.erc: - * Add /usr/share/emacs/site-lisp/erc/ to load-path - * (load "erc-auto") - - * debian/README.Debian: - * Info about the changes since last release updated - - * erc-pcomplete.el: * Fix emacs/xemacs compatibility - - * debian/scripts/install: * Don't compile erc-compat, fix ELCDIR - - * debian/control: * Change maintainer field - - * erc.el: - * (defin-erc-module): Renamed argument mode-name to mname because silly byte-compiler thought we were talking about `mode-name'. - - * Makefile: * Added debrelease target - - * erc-bbdb.el, erc-pcomplete.el, erc-stamp.el, erc.el: - * (define-erc-module): Added mode-name argument. - * Converted erc-bbdb, erc-pcomplete and erc-stamp to new macro. - * autoload fixes - - * erc-bbdb.el: - * Create a global-minor-mode (i.e., make it a proper erc-module) - - * erc.el: * (define-erc-module): New defmacro - -2002-11-16 Jorgen Schaefer - - * erc-autoaway.el(erc-autoaway-idle-seconds): - t in docstrings should be non-nil - -2002-11-16 Alex Schroeder - - * erc-autoaway.el, erc-button.el, erc-fill.el, erc-match.el, - erc-menu.el, erc-ring.el, erc-track.el: - Cleanup of file headers: copyright years, GPL mumbo-jumbo, commentaries. - - * erc-stamp.el(erc-insert-away-timestamp-function): - New custom type. - (erc-insert-timestamp-function): New custom type. - - * erc-fill.el(erc-fill-function): Doc, new custom type. - (erc-fill-static): Doc. - (erc-fill-enable): New function. - (erc-fill-disable): New function. - (erc-fill-mode): New function. - - * erc-match.el(erc-match-enable): add-hook for both - erc-insert-modify-hook and erc-send-modify-hook. - (erc-match-disable): remove-hook for both - erc-insert-modify-hook and erc-send-modify-hook. - -2002-11-15 Jorgen Schaefer - - * erc-autoaway.el: - - Added a way to use auto-away using emacs idle timers - - Renamed erc-set-autoaway to erc-autoaway-possibly-set-away for consistency - -2002-11-14 Jorgen Schaefer - - * erc.el: erc-mode-map: Removed the C-c C-g binding for erc-grab - - * erc.el: - (erc-server-341) Another instance of the channel/chnl problem i didn't - see last time - -2002-11-14 Alex Schroeder - - * erc-compat.el(erc-decode-coding-string): typo - -2002-11-14 Jorgen Schaefer - - * erc.el(erc-server-341): - variable name should be chnl not channel, as it is - used this way in this function, and the other erc-server-[0-9]* use - chnl too. - - * erc-autoaway.el: - Set back on all servers, not just the current one, since we're set - away on all servers as well. - - * HISTORY: Fixed typo (ngu.org => gnu.org) - - * erc-autoaway.el, erc-fill.el, erc.el: erc-autoaway.el: - * new file - - * erc.el: Removed auto-discard-away facility (now included in - erc-autoaway.el) - (erc-away-p): new function - - * erc-fill.el (erc-fill-variable): Check whether erc-timestamp-format - is bound before using it (erc-fill.el does not require erc-stamp). - -2002-11-10 Alex Schroeder - - * TODO: - TODO: moved it to https://www.emacswiki.org/cgi-bin/wiki.pl?ErcTODO - - * erc.el(with-erc-channel-buffer): Rudimentary doc string. - -2002-11-09 Alex Schroeder - - * erc-button.el(erc-nick-popup-alist): Made a defcustom. - - * erc-button.el(erc-button-disable): New function. - (erc-button-enable): New function, replaces the add-hook calls at top-level. - (erc-button-mode): New minor mode. - -2002-11-08 Alex Schroeder - - * erc-button.el(erc-button-entry): Use erc-button-syntax-table. - - * erc.el, erc-stamp.el: Doc changes. - - * erc-match.el(erc-match-mode): New function, replacing the - add-hook. - (erc-match-enable): New function. - (erc-match-disable): New function. - (erc-current-nick-highlight-type): Changed from 'nickname to 'nick - to make it consistent with the others. - (erc-match-message): Ditto. - - * erc-button.el(erc-button-syntax-table): New variable. - (erc-button-add-buttons): Use it. - -2002-11-06 Mario Lang - - * erc.el: - 1) (bug) ERC pops up a new buffer and window when being messaged - from an ignored person. fixed - 2) (misfeature) ERC notices the user in the minibuffer when it - ignores something - this can get very annoying, since the - minibuffer is also visible when not looking at ERC buffers. - Added a customizable variable for this, the default is nil. - 3) (wishlist) There is no IGNORE or UNIGNORE command. - Added. - 4) (wishlist) Some IRC clients, notably irssi, allow the user to - ignore "replies" to ignored people. A reply is defined as a - line starting with "nick:", where nick is the nick of an - ignored person. Added that functionality. - Done by Jorgen Schaefer - -2002-11-02 Alex Schroeder - - * erc.el(erc-connect): set-process-coding-system to raw-text. - -2002-11-01 Brian P Templeton - - * erc-pcomplete.el, erc-stamp.el, erc-track.el: - Fixed more autoloads - - * erc-compat.el: Added autoload for erc-define-minor-mode - -2002-11-01 Mario Lang - - * erc.el: * (erc-send-command): will break long messages into - a bunch of smaller ones, to prevent them from being truncated by the server. - The patch also axes some trailing whitespace. :-) - -2002-10-31 Alex Schroeder - - * erc-pcomplete.el(erc-compat): Require. - (erc-completion-mode): Use erc-define-minor-mode. - - * erc-track.el(erc-compat): Require. - (erc-track-modified-channels-mode): Use erc-define-minor-mode. - - * erc-stamp.el(erc-compat): Require. - (erc-timestamp-mode): Use erc-define-minor-mode. - - * erc-compat.el: New file with the code for erc-define-minor-mode, - erc-encode-coding-string and erc-decode-coding-string. Essentially - all the stuff that cannot be tested for using a simple boundp or - fboundp -- eg. because the number of arguments are wrong. - - * erc.el(erc-compat): Require. - (erc-process-coding-system): Moved to erc-compat.el. - (erc-connect): Do not set-process-coding-system. - (encode-coding-string): Compatibility code moved to erc-compat.el. - (decode-coding-string): Compatibility code moved to erc-compat.el. - (erc-encode-coding-string): Compatibility code moved to erc-compat.el. - (erc-decode-coding-string): Compatibility code moved to erc-compat.el. - -2002-10-27 Alex Schroeder - - * erc.el(erc-display-line-1): Removed call to - erc-decode-coding-string. - (erc-parse-line-from-server): Added call to - erc-decode-coding-string before anything gets parsed at all. - (erc-decode-coding-string): Use undecided coding system. - -2002-10-24 Sandra Jean Chua - - * erc-button.el, erc.el: - Added LASTLOG command and action for nick-button - -2002-10-22 Sandra Jean Chua - - * erc-pcomplete.el: - Fixed nopruning bug, added /MODE channel (mode) [nicks...] completion - mode not completed yet. - -2002-10-16 Sandra Jean Chua - - * erc-pcomplete.el: - Fixed 'Hi delysid:' bug in SAY completion after realizing that pcomplete on commands already took care of completing the initial nick: - -2002-10-15 Mario Lang - - * erc-pcomplete.el: update from sachac - -2002-10-13 Alex Schroeder - - * erc.el(erc-emacs-time-to-erc-time): Catch when tm is nil. - -2002-10-11 Andreas Fuchs - - * erc.el: - * Fixed `erc-scroll-to-bottom' to scroll to the bottom even when - in the middle of a line. Might also fix the Magic ECHAN Bug[tm]. (-: - -2002-10-11 Mario Lang - - * erc-nickserv.el: Fixed erc-networks for the opn->freenode change - -2002-10-08 Mario Lang - - * erc-pcomplete.el: - Make erc-completion-mode work interactively with already joined channel buffers - - * erc-chess.el: Add autoload cookies - - * erc-notify.el: Add pcomplete support - - * erc.el: - Remove autoload statements, remove autoload cookie from erc-mode and erc-info-mode - - * erc-fill.el, erc-match.el: add/remove autoload cookies - -2002-10-06 Alex Schroeder - - * erc-pcomplete.el(erc-completion-mode): New global minor mode - with autoload cookie. - (erc-pcomplete-enable): Renamed erc-pcomplete-initialize. - (erc-pcomplete-disable): New function. - - * erc-complete.el: Doc changes. - - * erc-stamp.el(erc-stamp-enable): Renamed erc-stamp-initialize. - (erc-stamp-disable): Renamed erc-stamp-destroy. - (erc-timestamp-mode): Use new names. - - * erc.el: Removed autoload for erc-complete and - erc-track-modified-channels-mode -- the autoload cookie should do - that instead. - (erc-input-message): Doc string, removed binding for erc-complete. - (erc-mode-map): Removed binding for erc-complete. - -2002-10-03 Mario Lang - - * erc-notify.el: - New functions erc-notify-JOIN and erc-notify-QUIT to catch some common cases (warning, untested) - -2002-10-01 Alex Schroeder - - * erc-stamp.el(erc-timestamp-mode): New function. Removed call - to erc-stamp-initialize at the end. - -2002-09-25 Brian P Templeton - - * erc.el: - Added customizable `erc-process-coding-system' variable. - -2002-09-22 Brian P Templeton - - * erc-fill.el: - `erc-fill-variable' now does the right thing when `erc-hide-timestamps' is non-nil - -2002-09-21 Mario Lang - - * erc-fill.el: - patch from Peter Solodov (note, its slightly broken still - -2002-09-05 Mario Lang - - * erc-pcomplete.el: Added LEAVE as alias for PART - -2002-09-04 Mario Lang - - * erc-pcomplete.el: - By sachac (good work!) keep up doing such things - -2002-08-31 Mario Lang - - * erc.el: - A fix for Bug#133267: now you can put (erc-save-buffer-in-logs) on erc-insert-post-hook to save *every* incoming message. - -2002-08-30 Brian P Templeton - - * erc.el: - Changed default value of erc-common-server-suffixes because of the OPN - name change - -2002-08-28 Mario Lang - - * erc-stamp.el: Try to reactivate isearch in xemacs - - * erc-stamp.el: - fixes issues related to comparative emacsology and a silly bug - -2002-08-27 Mario Lang - - * erc.el: - New hook erc-send-completed-hook (for robot stuff), changed alexanders email address to reflect reality, little fix to erc-auto-query to get a bit of a speedup - -2002-08-22 Mario Lang - - * erc-button.el: - Fixed case-fold-search (thanks sachac), now lambda works in erc-button-alist, added wardwiki+google+symvar+rfc+itime regexps from the wiki - -2002-08-19 Mario Lang - - * erc-button.el: - erc-nick-popup-alist: New variable to make erc-nick-popup configurable - -2002-08-16 Alex Schroeder - - * erc-button.el(erc-recompute-nick-regexp): Fixed regexp. - - * erc-button.el(erc-button-buttonize-nicks): Changed custom type - to integer. - (erc-button-add-buttons): Moved button removal code to new - function. - (erc-button-remove-old-buttons): New function. - (erc-button-add-button): Removed use of overlays and used - erc-button-add-face instead. - (erc-button-add-face): New function to merge faces as text - properties. This should be much faster when lots of buttons - appear. - (erc-button-list): New helper function. - - * erc.el(erc-display-message): Fixed argument list. - (erc-display-prompt): Reduced calls to length, use start-open - property for XEmacs to prevent a little box of erc-prompt-face at - the end of messages other people send. - (erc-refresh-channel-members): Fix XEmacs calls to split-string, - which may return an empty string at the end of the list. This - would cause hangups in erc-button in re-search-forward loops. - (erc-get-channel-mode-from-keypress): Replaced control codes with - octal escape sequences. - -2002-08-14 Mario Lang - - * erc-button.el: Try to be compatible to XEmacs regexp-opt. (I'm - going to quit this job if I find more of those damn differences.) - - * debian/README.Debian, debian/scripts/install: - * Added info to README.Debian - * Finished debian/scripts/install - -2002-08-13 Mario Lang - - * debian/scripts/install: First attempt to fix it - - * debian/README.Debian, debian/changelog, debian/scripts/install: - changelog: Changed maintainer and added new entry - README.Debian: Re-explained the byte-compile issue - scripts/install: Exclude erc-bbdb|chess|ibuffer|speedbar from - byte-compiling - - * erc-track.el: Added C-c C-SPC in addition to C-c C-@ - - * erc-notify.el: Little docstring change - -2002-08-09 Mario Lang - - * erc-stamp.el: - Change one use of set-text-properties to add-text-properties (tnx Lathi) - -2002-08-02 Mario Lang - - * erc-stamp.el: added erc-timestamp-only-if-changed-flag - -2002-07-22 Mario Lang - - * erc.el: - Removed timestamp related code and moved into erc-stamp.el - - * erc-stamp.el: - Timestamping code moved out of erc.el. Additional, now we can timestamp either on the left or on the right side - -2002-07-16 Mario Lang - - * erc.el: - * Make ctcp ping return its message in the active buffer, instead of the server buffer - * Corrected minimal typo in catalog - * Added var and variable as alias for /set - -2002-07-08 Mario Lang - - * erc-track.el: - * New function erc-track-switch-buffer (by resolve) - Bound to C-c C-SPC, enjoy! - -2002-07-08 Gergely Nagy - - * debian/changelog: New snapshot deb - - * debian/scripts/install: Rewrote in make. - Does not byte-compile erc-speak.el at all, and excludes erc-track.el too, if - ran for xemacs. - - * debian/control: Added dependency on make - - * debian/copyright: Updated copyright info - - * debian/rules: Use $(wildcard *.el) instead of a hardcoded list - -2002-07-03 Diane Murray - - * erc.el: - erc-iswitchb now works correctly if erc-modified-channels-alist is non-nil - -2002-07-01 Diane Murray - - * erc-menu.el: - * changed how we check if we should activate "Track hidden channels" and - whether it should be selected - fixes a bug XEmacs where whole menu bar - does not work if menu is loaded - - * erc-menu.el: - * added "Disconnect from server", only selectable if erc-connected is non-nil - - * topic is allowed to be set by normal users if channel mode is not +t - - * add " ..." after description if arguments needed after selecting menu item - - * only allow selecting of menu points needing a channel if current buffer is - a channel buffer - done by testing if channel-members is non-nil - - * put erc-match functions in new group "Pals, fools and other keywords" - - * erc.el: - * moved definition of erc-show-my-nick to GUI variables section - - * erc-connected variable now defined with defvar - now set in channel and query buffers, was only in server buffer before - upon disconnect, set erc-connected to nil in all the server's buffers - - * added erc-cmd-GQUIT and its alias erc-cmd-GQ - quit all servers at once - - * added interactive function erc-quit-server, bound to C-c C-q - - * added erc-server-WALLOPS - - * added WALLOPS to english catalog, fixed s461 (was showing message twice) - - * typo fixes, spacing change - -2002-06-29 Mario Lang - - * erc.el: Use pp-to-string in /set (without args) - - * erc-netsplit.el: - Make /set anonymous-lign set erc-anonymous-login, also report - which var was set to which val. - -2002-06-28 Diane Murray - - * erc-menu.el: added "Customize ERC" - -2002-06-25 Mario Lang - - * erc.el: New variable: erc-use-info-buffers, defaults to nil. - This prevents info-buffers from being created/updated. - Set to t if you use :INFO buffers. - (by rw) - Delete (erc-display-prompt) from reconnect to avoid clutter - -2002-06-23 Diane Murray - - * erc.el: - erc-get-channel-mode-from-keypress is now bound to C-c C-m - erc-insert-mode-command is taken care of by this function as well - -2002-06-21 Mario Lang - - * erc-track.el: - Fixed bug where buffer-names suddenly had text-properties. - -2002-06-19 Diane Murray - - * Makefile: changed erc-auto.el to $(SPECIAL) in make fullclean - - * Makefile: remove erc-auto.el on make fullclean - -2002-06-18 Diane Murray - - * erc-match.el: fixed spelling error - - * erc-track.el, erc-match.el: * erc-match.el: - highlight current nickname in its own face (inactive by default): - - added erc-current-nick-highlight-type, erc-current-nick-face, - erc-current-nick-p - - * erc-track.el: - added support for erc-current-nick-face - -2002-06-17 Diane Murray - - * erc.el: * added beginning support for 005 numerics: - - added buffer local variable erc-server-parameters - - added erc-server-005, which sets erc-server-parameters if the server has - used this code to show its parameters - -2002-06-16 Diane Murray - - * erc.el: - * bugfix: when pasting lines with blank lines in between, remove the blank lines - but send the rest - - * since we know the command, use it when checking what's in erc-hide-list - added check to erc-server-KICK - - * added some blank lines for better readability - -2002-06-16 Alex Schroeder - - * erc-nickserv.el(erc-nickserv-alist): Fixed typo. - -2002-06-15 Alex Schroeder - - * erc-nickserv.el(erc-networks): Added doc string. - (erc-nickserv-alist): Added doc string. - -2002-06-14 Diane Murray - - * erc-ring.el: - fixed bug so that the prompt and command always get put at the end of the buffer - -2002-06-10 Mario Lang - - * erc-nickserv.el: Added iip support. - Added :type for erc-nickserv-passwords custom. - Fixed hook usage. - -2002-06-07 Diane Murray - - * erc-nickserv.el: * added GalaxyNet - - * erc-nickserv-alist: - - sorting networks alphabetically - - added two more pieces of information in erc-nickserv-alist: - word to use for identification and whether to use the nickname - - * erc-current-network: - - made regex case insensitive, downcase server to match - - uses the new information - - now uses new variable erc-networks instead of doing checking manually - - * added variable erc-networks - - * fixed some indentation, documentation - -2002-06-07 Mario Lang - - * erc.el: Fix for kill-buffer hook stuff - -2002-06-06 Mario Lang - - * erc.el: Added /squery command - -2002-06-06 Diane Murray - - * erc-menu.el: * made group Channel modes - - moved change mode and invite only mode to here - - added secret, moderated, no external send, topic lock, limit, key - - * check that user is in a channel buffer and user is a channel operator - for all op-related actions - - * "Identify to nickserv" needs erc-nickserv-identify defined - - * added "Show ERC version" - - * erc.el: - * added erc-set-channel-limit, erc-set-channel-key, erc-toggle-channel-mode - - * added erc-get-channel-mode-from-keypress, which is bound to C-c m - sends the next character which is typed to one of the 3 new functions - - did not remove erc-invite-only-mode and it's key binding in case - people are used to it, although it probably should be removed... - - * in erc-server-MODE: - added check if tgt equal to user's nick - removed erc-display-line, only using the erc-display-message - - * added s461 to english catalog - - * fixed bug where XEmacs would not quit if erc-quit-reason was - set to erc-quit-reason-various and assoc-default was not defined - -2002-06-04 Andreas Fuchs - - * erc-ezbounce.el, erc-match.el: - * erc-ezbounce.el: Added. Provides support for ezbouncer; automatic login, - session management implemented. I've contacted the author - about stuff in EZBounce's logging. - * erc-match.el: Fixed a stupid mistake where - "*** Your new nick is " would trigger an error. - -2002-06-04 Diane Murray - - * erc-nickserv.el, erc.el: * added erc-nickserv.el - * moved nickserv identification variables and functions to the new file - (require 'erc-nickserv) is now necessary for this to work - - * erc.el: - * results of /COUNTRY now formatted as notice; errors are ignored, - fixing - bug which made prompt disappear - - * added undefined-ctcp error message to english catalog - - * changed some (when (not erc-disable-ctcp-replies) to use unless instead - and some if's without else statements to use when or use - - * CTCP replies now use erc-display-message, formatted as notices - - * added following to english catalog: - - undefined-ctcp - - CTCP-CLIENTINFO, CTCP-ECHO, CTCP-FINGER, CTCP-PAGE, CTCP-PING, - CTCP-SOUND, CTCP-TIME, CTCP-UNKNOWN, CTCP-VERSION - - s303, s305, s306, s353 - - * split erc-server-305-or-306 into erc-server-305 and erc-server-306 - - * KICK already had buffer set, using it - - * erc.el: - * erc-format-timestamp now only called from erc-display-message and - erc-send-current-line - - * all instances of erc-display-line with erc-highlight-error - changed to use erc-display-message - - * added following error messages to english catalog: - bad-ping-response, bad-syntax, cannot-find-file, cannot-read-file, - ctcp-request, flood-ctcp-off, flood-strict-mode, no-default-channel, - no-target, variable-not-bound - - * added following server related messages to english catalog: - s324, s329, s331, s332, s333, s341, s406, KICK, KICK-you, KICK-by-you, MODE-nick - - * ignoring server codes 315, 369 - - * added erc-server-341, erc-server-406 - - * channel topic and mode notices displayed in respective channel buffers if they - exist - - * erc-server-KICK: display the message before removing this channel so that we - can track the kick - - * send parsed to erc-ctcp-query-ACTION-hook so that actions can be checked - by erc-match - - * fixed bug where nil was shown if no reason was given by users on /PART - -2002-06-03 Diane Murray - - * erc-match.el: - * fixed bug where erc-log-matches produced an error when the value of - (erc-default-target) was not a channel - * use erc-format-timestamp, if it's non-nil, for %t in erc-log-match-format - -2002-06-01 Diane Murray - - * erc-button.el: - * made action case insensitive in erc-nick-popup and added a more descriptive - error message - -2002-05-30 Brian P Templeton - - * erc.el: - Removed multiple calls of `erc-prompt' in `erc-display-prompt' - -2002-05-29 Mario Lang - - * erc.el: - First step timestampkiller cleanup. I'm tired, do the rest tomorrow. - - * erc.el: - New functionality: Catch channel/server buffer kills through kill-buffer-hook. - Currently, it only does a PART if you kill a channel buffer. - -2002-05-28 Mario Lang - - * erc.el: - defvar'ed some buffer-local variables to make elint at least a bit more happy. - Moved comments into docstrings. - Changed some instances of member to memq. - - * erc-track.el, erc.el: - * erc.el (erc-message-type-member): New function, used to test - for message type. Require erc-parsed text-property. - * erc-track.el (erc-track-exclude-types): New variable. Defaults - to ("JOIN" "PART") right now for testing, it should eventually set - to nil soon again. - (erc-track-modified-channels): Use above fun and var to optionally - exclude certain message types from channel tracking. - -2002-05-28 Diane Murray - - * CREDITS: added myself, vain as it sounds ;) - -2002-05-25 Mario Lang - - * erc.el: * Some small docstring fixes - * (erc-display-line): Now takes also a process object in the buffer argument. - Used for easy sending to the server buffer. - * Several places: Just pass proc, not (process-buffer proc) - -2002-05-24 Mario Lang - - * erc.el: Mostly docstring fixes/additions - - * erc-netsplit.el: Doc fixes, and a new netjoin-done message. - - * erc-fill.el: Doc fixes, erc-fill custom group, autoloads. - - * erc-netsplit.el: Fix to erc-netsplit-timer. - - * erc-netsplit.el: Fixed a silly typo - - * erc-maint.el: is this really necessary? - - * erc.el: Added new variable erc-hide-list. - It affects erc globally right now, and is used to hide certain IRC type messages like JOIN and PART. - - * Makefile: Doh, I should really test this before checkin :) - - * Makefile: Silly cut&paste bug fixed - - * erc-list.el: Added autoload cookie - - * erc-match.el: Added missing require erc. - - * erc-notify.el: Autoload cookies and a -initialize function. - - * erc-chess.el: Added autoload cookies - - * Makefile: Finally, we have a Makefile. - Primarily used for autoload definition generation right now. - - * erc-auto.in: First version. - - * erc-track.el: Added autoload cookie - - * erc-netsplit.el: - New module, used to autodetect and hide netsplits. - (Untested, no netsplit happened yet :) ) - - * erc-nets.el: Added some old code I once worked on. - Added autoload cookie - -2002-05-24 Diane Murray - - * erc-fill.el: - removed reference in documentation to old variable, changed it to the new one - - * erc.el: - * added new function erc-connection-established which is called after receiving - end of MOTD (does nothing if it's been called before) - - * added new hook erc-after-connect which is called from - erc-connection-established with the arguments server (the announced server) - and nick - which other arguments should be sent?? - - * added buffer variable erc-connected which is set to t the first time - erc-connection-established is called, set to nil again if we've been - disconnected - - * set initial user mode - - added custom variable erc-user-mode which can be a string or a function - which returns a string - - new function erc-set-initial-user-mode gets called from - erc-connection-established - -2002-05-22 Diane Murray - - * erc.el: fixed bug where prompt was missing after reconnect - -2002-05-21 Diane Murray - - * erc.el: - in erc-nickserv-identify: if network is unknown, just use "Nickserv" - - * erc.el: * fixed some typos - - * timestamping - - ctcp request messages and replies now have timestamp - - timestamps in front of error messages now in timestamp face - - added timestamp to more error messages - - * ctcp reply messages, server ping message updated - - * added variable erc-verbose-server-ping - check this instead of erc-paranoid - - * added whowas on no such nick: - - added variable erc-whowas-on-nosuchnick - - in erc-server-401 do WHOWAS if erc-whowas-on-nosuchnick is non-nil - - * erc.el: forgot documentation for erc-nickserv-alist - - * erc.el: NickServ identification changed and enhanced: - - erc-nickserv-identify-autodetect now called from erc-server-NOTICE-hook - - now possible to identify automatically without prompt: - - added custom variables erc-prompt-for-nickserv-password and - erc-nickserv-passwords - - added erc-nickserv-alist containing the different networks' nickserv details - - added function erc-current-network to determine the network symbol - - fixed bug where identification on dalnet didn't work, because they now - require NickServ@services.dal.net - now sends to all NickServ with nick@server where possible - -2002-05-17 Diane Murray - - * erc-fill.el: - * filling with erc-fill-variable now works with custom defined fill width: - - changed erc-fill-column from defvar to defcustom - - in erc-fill-variable: set fill-column to value of erc-fill-column - - * erc.el: erc.el: - * fixed bug where topic wasn't being set when channel name was provided - - erc-fill.el: - * filling with erc-fill-variable now works with custom defined fill width: - - changed erc-fill-column from defvar to defcustom - - in erc-fill-variable: set fill-column to value of erc-fill-column - -2002-05-16 John Wiegley - - * erc.el: whitespace fix - -2002-05-15 Diane Murray - - * erc.el: - * added explanation of empty string working in erc-quit-reason-various-alist - * removed the text property from erc-send-message, it caused problems - with /SV (as noticed by gbvb on IRC) and is obviously not needed - * when receiving a ctcp query, convert type to uppercase to allow for - "/ctcp nick time" and not just "/ctcp nick TIME" - * timestamp in front of server notices now shown in the timestamp face - -2002-05-13 Diane Murray - - * erc.el: - - in erc-format-privmessage: `erc-format-timestamp' added to message after - message's text properties are applied so that it doesn't lose its face - - - /quit without reason now works when `erc-quit-reason' is set to - `erc-quit-reason-various' and the empty string "" is defined in - `erc-quit-reason-various-alist' - -2002-05-13 Andreas Fuchs - - * erc-bbdb.el: - * Applied Drewies patch to pop-up on nick changes when -popup-type is 'visible - -2002-05-12 Andreas Fuchs - - * erc-bbdb.el, erc.el: - * erc-bbdb.el: pop up the buffer on /whois when erc-bbdb-popup-type is 'visible - * erc.el: fix for empty quit reason problem by drewie. - -2002-05-12 Mario Lang - - * erc.el: disumu nick patch - - added erc-show-my-nick (default t) - if t, show nickname like - if nil, only show a > character before the message - - added faces erc-nick-default-face and erc-nick-msg-face - - nicknames (channel, msgs, notices) are now in bold face by default - - the msg face matches the erc-direct-msg-face color - -2002-05-10 Alex Schroeder - - * erc.el(erc-send-pre-hook): Doc change. - - * CREDITS: Alexander L. Belikoff is confirmed original author. - -2002-05-10 Mario Lang - - * erc.el: - timestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumutimestamp fix by disumu - -2002-05-09 Mario Lang - - * erc.el: *** empty log message *** - -2002-05-06 Mario Lang - - * erc.el: - New var: erc-echo-notices-in-minibuffer-flag. defaults to t. - -2002-05-04 John Wiegley - - * TODO: *** empty log message *** - -2002-05-03 Alex Schroeder - - * erc.el: Copyright notice, version string updates. - -2002-05-02 Alex Schroeder - - * erc.el: Comment: dme is David Edmondson - -2002-05-01 Alex Schroeder - - * erc.el(erc-warn-about-blank-lines): New option. - (erc-send-current-line): Use it. - (erc-quit-reason-various-alist): New option. - (erc-quit-reason): New option. - (erc-quit-reason-normal): New function. - (erc-quit-reason-zippy): New function. - (erc-quit-reason-various): New function. - (erc-cmd-QUIT): Use them. - -2002-04-30 Alex Schroeder - - * erc.el: Version 2.92 - - * erc.el(erc-send-modify-hook): Default value is nil. - -2002-04-27 John Wiegley - - * erc.el: - Don't redisplay the prompt if the ERC buffer is no longer alive. - -2002-04-26 John Wiegley - - * erc.el: - Don't call `set-buffer' on old-buf unless the buffer is valid. It's - often not when separate frames are being used. - -2002-04-23 Mario Lang - - * erc-button.el: fixed up erc-nick-regexp - -2002-04-22 Brian P Templeton - - * erc.el: - `erc-prompt' may now be a function that returns a string (which is - used as the prompt). I don't use Customize but I think customization - of it may be broken if it's not a string. - - There is a new `erc-prompt' function that returns the prompt as a - string (e.g., returning either the result of `(funcall erc-prompt)' or - `erc-prompt'). - - This allows for dynamic prompts, such as a LispWorks-like prompt, or - one containing simply the current channel name. It was requested by - Mojo Nichols (nick michols) in #emacs today, 21-Apr-2002; cf. the - #emacs logs at - - * erc.el: - fix erc-send-current-line to work on empty lines again (without sending the prompt) - Fix C-c C-t to not include the nick/time info - (both from antifuchs) - - * erc-complete.el: Fix for xemacs elt behavior - -2002-04-17 John Wiegley - - * erc-chess.el: - Added a missing arg in a call to erc-chess-handler. - -2002-04-15 John Wiegley - - * erc-chess.el: *** empty log message *** - -2002-04-14 John Wiegley - - * erc-chess.el: *** empty log message *** - -2002-04-12 John Wiegley - - * erc-chess.el: *** empty log message *** - - * erc-chess.el: bug fixes - - * erc-chess.el: *** empty log message *** - -2002-04-12 Mario Lang - - * erc-chess.el: change order. - - * erc-chess.el: more fixing. - - Now, the 'match question works. It sends an accept back. - But display popup doesn't work.. - - * erc-chess.el: fixup (still far from working) - -2002-04-11 Mario Lang - - * erc.el: - * Added :options entry for erc-mode-hook (erc-add-scroll-to-bottom) - -2002-04-11 John Wiegley - - * erc.el: remove trailing \n from any sent text - - * servers.pl, erc-bbdb.el, erc-button.el, erc-chess.el, - erc-complete.el, erc-fill.el, erc-ibuffer.el, erc-list.el, - erc-match.el, erc-menu.el, erc-nets.el, erc-replace.el, - erc-speak.el, erc-speedbar.el, erc-track.el, erc.el: - clean whitespace - - * erc.el: Replaced erc-scroll-to-bottom. - -2002-04-11 Mario Lang - - * erc-track.el: - try to fix behavior when used with different frames. - -2002-04-09 Mario Lang - - * erc-chess.el: - fixup release, far from ready for real usage, but it appears to work. - - * erc.el: - speed improvements based on elp-instrument-package RET erc- RET results - - * erc-chess.el: initial version. - please test it - Get chess.el from johnw's cvs: - cvs -d:pserver:anonymous@alice.dynodns.net:/usr/local/cvsroot login - cvs -d:pserver:anonymous@alice.dynodns.net:/usr/local/cvsroot co chess - - (as usual, blank password) - - Add the resulting dir to your load-path and require erc-chess. - - Usage: Just do /chess nickname - The remote end much use erc, as no other irc client I know of supports this ... - - See erc-chess-default-display and maybe set it to chess-images or chess-ics1 if you prefer those over chess-plain. - Also, see erc-chess-user-full-name to set the name you use in chess games. - -2002-04-04 Mario Lang - - * erc.el: New hackery latenightwise - - * erc.el: upupadowndowncase - -2002-04-04 Gergely Nagy - - * debian/changelog: Updated for the new snapshot - - * debian/rules: Install README.Debian into the package - - * debian/README.Debian: Initial check-in - -2002-04-04 Mario Lang - - * erc.el: - Fixed that /me in query buffers ended up in server buffer - - * erc.el: * Implemented joining +k channels - -2002-03-14 Mario Lang - - * erc.el: New utility function: erc-channel-list - minor fix to erc-get-buffer. hopefully that helps shapr - -2002-03-12 Mario Lang - - * erc.el: - New /command: /QUOTE for sending directly to the IRC server - Removed erc-fill from erc-insert-modify-hook. To activate filling, simply customize that var. - -2002-03-09 Brian P Templeton - - * CREDITS: *** empty log message *** - -2002-03-09 Mario Lang - - * erc-complete.el: - New variable: erc-nick-completion-ignore-case. Defaults to t. - - * erc-track.el: - * erc-track-shorten-name-function can now be set to nil to avoid treating of channel names at all. - -2002-03-06 Gergely Nagy - - * debian/changelog, debian/rules: update to new snapshot - -2002-03-06 Mario Lang - - * erc.el: - Fixed nasty bug which prevented channel limit from correctly display/handling - - * erc-track.el: Made shortening code highly customizable. - Now, there is the variable erc-track-shorten-function which holds - a function which gets called with one argument, CHANNEL-NAMES, which is a list - of strings of the channel names. - It needs to return a list of strings of the same length with the modified values... - - * erc-track.el: - Added erc-track-shorten-aggressively, default to nil - if it is set to t, erc will shorten a bit more. - if nil, erc will shorten the name only if it would get shorter than just - one char... - - * erc-speak.el: added iirc to the abbreviation expansion list. - - * erc-track.el: - Added customization variable: erc-track-use-faces. defaults to t. - - * erc-track.el: *** empty log message *** - - * erc-track.el: - experimental: Added face support to mode-line channel activity tracker. - Currently we use the faces used for indicating in the buffer (erc-pal-face for channels with pal activity...) - -2002-03-05 Mario Lang - - * erc-complete.el: * added docfixes (thanks ore) - - * erc-track.el: Fixed channel-name reduction. - thanks again alex. - Renamed the vars to erc-track-opt-start and erc-track-opt-cutoff. - - * erc.el: fixed another silly error - - * erc-track.el: Implemented channel name shortening. - Vars erc-track-cutoff says: all channel names longer than this will be shortened. - Var erc-track-minimum-channel-length says: don't make names shorten than this. - (Thanks go out to kensanata for the nice unique-substrings utility function). - - * erc.el 2002-07-15T00:01:34Z!raeburn@raeburn.org: silly typo corrected - - * erc.el: New variable: erc-common-server-name-suffixes - This alist can be used to change the server names displayed in mode-line - to a shorter version.. - * New function: erc-shorten-server-name (uses var above) - * Changed erc-prepare-mode-line to use erc-shorten-server-name. - -2002-02-25 Mario Lang - - * erc.el: - CTCP handling rewritten. Seems to work. please test and report probs. - -2002-02-24 Mario Lang - - * erc.el: - Fixed emacs20 backward compatibility (new defun/alias: erc-propertize) - -2002-02-22 Mario Lang - - * erc-button.el: *** empty log message *** - -2002-02-21 Mario Lang - - * erc-button.el, erc.el: - minor fixup related to read-only prompts and command renaming. - -2002-02-21 Andreas Fuchs - - * erc.el: * modify `erc-remove-text-properties-region' to work. - Could even be a little faster now. (-: - -2002-02-21 Mario Lang - - * erc-ring.el: - fixed erc-replace-command to behave right when text is read-only. - Also, use erc-insert-marker and (point-max) now. - - * erc.el: * Made erc-prompt read-only - * new function: erc-make-read-only. Can be used on erc-insert-post-hook and erc-send-post-hook to ensure read-only buffer text too - -2002-02-19 Mario Lang - - * erc-list.el: added comment to docstring - - * erc-speak.el: minor updates, use erc-nick-regexp now - - * erc.el: - ensure that erc-timer-hook is called inside the server-buffer. - -2002-02-19 Andreas Fuchs - - * erc-match.el: - * Probably fixed the "number-char-or-marker-p: nil" bug. - -2002-02-19 Mario Lang - - * erc-notify.el: Initial release. - - * erc.el: added #303 handling - moved timer and added an arg (erc-current-time) - - * erc-list.el, erc.el: - slightly changed the erc-once-with-server-event macro - - * erc-button.el: erc-button-alist: doc fix and custom type fix - -2002-02-18 Mario Lang - - * erc-list.el, erc.el: new macro: erc-once-with-server-event - erc-list.el: use it - - * erc-match.el: - Minor fix related to hook call method change (-until-seccess now) - - * erc.el: fixed ctcp behavior abit (with auto-query on) - - * erc-list.el: ChanList mode. - Load it, and type M-x erc-chanlist RET - Demonstrates how the new hook system can be nicely used. - - * erc.el: - new hook: erc-default-server-hook. This one gets called if we don't have anything defined for a certain IRC server message. - New function: erc-default-server-handler. (used by above hook). - New function: erc-debug-missing-hooks: Used by above hook to save a list of unimplemented server messages. - New function: erc-server-buffer, erc-server-buffer-p. - Various places: use it. - Minor fixup. - - * erc-button.el: fix regexp to not buttonize ~user@host hostnames - -2002-02-17 Mario Lang - - * erc-complete.el, erc.el: Eliminated erc-command-table - Upcased the command defuns (erc-cmd-join is now erc-cmd-JOIN) - Fixed erc-complete to not require erc-command-table. - Implemented erc-cmd-HELP - (You have to try that, its too coool!) - e.g. /help auto-q - fixed autoloads for erc-add-pal and so on to be interactive. - -2002-02-17 Andreas Fuchs - - * erc-match.el: - * Fix unfunctional code in `erc-get-parsed-vector-type'. - - * erc-bbdb.el, erc-button.el, erc-match.el, erc.el: - * Be careful: MANY changes ahead. I won't go into too much details. - - * erc.el, new file erc-match.el: split out all pattern-matching code. - * erc.el: removed all defcusts for erc-{...}-highlight-props. They are - quite useless, anyway. - * moved erc-add-entry-to-list and -remove- over to erc-match. changed - their arg list. - * erc.el: add autoloads for erc-{add,delete}-{keyword,pal,fool,dangerous-host} - * erc.el: erc-server-PRIVMSG-or-NOTICE: - - remove all the highlighting crap - - add a (when (eq s nil) ...) so that untreated CTCP messages don't - get misdisplayed. - * erc.el: erc-mark-message: removed this function, it's useless - * erc.el: minor bugfixes. - - * erc-match.el: first checkin. This file now contains all the pattern - matching stuff. there is now another defcust group, erc-match, - containing all match related stuff (erc-keywords, ...) - * erc-match.el: added functionality to log matching lines. Quite - customizable, check out the docstring of defun erc-log-matches - * erc-match.el: added functionality to make foolish messages - invisible/intangible. This could replace erc-ignore-list - sometime. it's more powerful right now, anyway. - * erc-match.el erc-text-matched-hook: new hook. run when Text matches - anything (pal, fool, etc.). - - * erc-button.el: Make nick buttonization customizable. - * erc-button.el: Give nick buttonization a lower priority so that it - does not break url buttons. - - * erc-bbdb.el: Add \n to the separators by which we split nicknames. - -2002-02-17 Mario Lang - - * TODO: Added item - -2002-02-17 Brian P Templeton - - * CREDITS, erc.el: Added invisible timestamp support. - -2002-02-16 Gergely Nagy - - * debian/changelog, debian/rules, debian/scripts/install: - updated to new snapshot - -2002-02-16 Mario Lang - - * erc.el: - Fixed channel limit format overflow in mode-line display. - (Having to use floats if integers are to large is quite strange, isn't it?) - - * TODO: TODO list created. - Add comments and expand it. - - * erc.el: Fixed bug in query buffer handling (only happened in - mixed-case situations) - - * erc.el: shapr checkdoc patch #1 - massive docfixes! yay, keep going! - -2002-02-15 Mario Lang - - * erc.el: various other fixes - make s301 a catalog entry - -2002-02-15 Andreas Fuchs - - * erc.el: * erc-server-NICK and erc-server-INVITE: fixed to use - `erc-display-message'. These I missed in the first checkin. I - didn't say it in the last log message, but please test these. - - * erc-fill.el, erc.el: - * erc.el: updated many functions to use `erc-display-message'. Now, we - should go for getting highlighting out of - erc-server-PRIVMSG-or-NOTICE. The part I want to attack has been - marked. - * erc-fill.el: updated static filling to leave the erc-parsed property alone. - -2002-02-15 Mario Lang - - * erc.el: - first step, new function: erc-display-message - - * erc.el: added numreply 379 and 405. - - * erc.el: stupid typo fixed - - * erc.el: - Finally renamed erc-frame-dedicated-p to erc-frame-dedicated-flag - Removed usage of erc-interpret-controls from info buffer drawing (major speedup) - Other speedups based on the results from elp. - ERC is now about 300%-500% faster in some situations with very full channels!!!!! - -2002-02-14 Andreas Fuchs - - * erc.el: - * erc-downcase now downcases {}|^ with []\~ -- 'stolen' from zenirc. - * various checkdoc fixes. Just the upper third of the file, but that - should help a little, too. (-: Again, if you have any writing - skills, take out that dusty keyboard and tap it to the beat of M-x - checkdoc! - -2002-02-14 Gergely Nagy - - * erc.el(erc-format-privmessage): - fix it, so timestamp-coloring works again (patch from antifuchs) - -2002-02-14 Mario Lang - - * erc.el: Many fixes based on M-x checkdoc RET. - If you have write access, and some english knowledge, help document erc too! - M-x checkdoc RET, and follow the instructions. - - * erc-button.el, erc-ibuffer.el: minor fixes - - * erc.el: Use nreverse instead of reverse. - Use eq instead of equal where possible. - Rewrote erc-get-buffer to not use find-if (find-if does very deep function-call nesting, which isn't good in a defun which is called so often) - -2002-02-13 Mario Lang - - * erc-button.el, erc.el: - In erc.el, new hook: erc-channel-members-changed-hook. - erc-button.el: Now highlight all nicknames. uses regexp-opt. - -2002-02-04 Mario Lang - - * erc-nets.el: - Database of irc networks. Use erc-server-select to interactively select one. - - * erc.el: * erc-format-nick-function: New variable. - * (erc-format-nick): The default for above var. Just return the nick. - * (erc-format-@nick): Prefix NICK with @ or + if OP or VOICE. - * Removed erc-track-modified-channels related code and moved into erc-track.el - Its auto-loaded now - - * erc-track.el: Split code from erc.el - -2002-02-01 Mario Lang - - * erc-ibuffer.el: - * erc-target now uses erc-port-to-string - - * servers.pl: - Script to convert mircs servers.ini to a elisp salist kind of thing. - (development tool, it doesn't help you much as a user) - - * erc.el: - * erc-display-line-buffer: renamed to erc-display-line-1 - * erc-port-equal: New function. - * erc-normalize-port: Used by erc-port-equal - * minor docstring fixes - -2002-02-01 Andreas Fuchs - - * erc.el: - * erc-already-logged-in-p: compare ports is more robust now. - - * erc-button.el: * Add buttonization to erc-send-modify-hook, too - -2002-01-31 Mario Lang - - * erc.el: - Use insert-before-markers instead of insert in erc-display-line-buffer - This fixed point@column 0 problem and gives us some speedup! yay - - * erc-ibuffer.el, erc.el: minor fixes - - * erc.el: - * (erc-line-beginning-position): Renamed to erc-beg-of-input-line. - * (erc-line-end-position): Renamed to erc-end-of-input-line. - * erc-multiline-input-p: Variable removed. - - * erc.el: - Minor docstring fixes (using M-x checkdoc-current-buffer) - If you find time, and you are native english speaker, do that too!! - - * erc.el: fixed macro-invocation - -2002-01-31 Andreas Fuchs - - * erc.el: * erc-with-all-buffers-of-server: use erc-list-buffers - * erc-process-away, erc-{save,kill}-query-buffers: use it. - * erc-cmd-away-all: new command. Set away/back on all servers. - - * erc.el: - * Fix last multiline bug in erc-send-distinguish-noncommands. - -2002-01-31 Mario Lang - - * erc-ibuffer.el, erc.el: minor fixes - -2002-01-30 Mario Lang - - * erc-ibuffer.el, erc-menu.el, erc-speak.el, erc.el: - Renamed erc-track-modified-channels-minor-mode to erc-track-modified-channels-mode (at least, its a bit shorter) - Added docstring to erc-server-hooks (through the macro) - Minor docfix in obsolete hook - -2002-01-30 Andreas Fuchs - - * erc.el: - * erc-send-current-line: fix behavior where buffer changes. - * erc-mark-message: fix stupid face bug. highlighting of pals should work now. - - * erc-ring.el, erc.el: - * new hooks: erc-send-pre-hook, erc-send-modify-hook, erc-send-post-hook - * erc-send-this: new variable - * erc-noncommands-list: new constant. - * erc-send-distinguish-noncommands: use it. (First filter function for sending! yay!) - * erc-send-current-line: nearly completely rewritten. - - now handles multiline input. (yay!) - - now uses the three hooks from above. - * erc-process-line: new arg, no-command: don't process this line as a command. - -2002-01-30 Mario Lang - - * erc-bbdb.el, erc-button.el, erc-speak.el, erc.el: - hook handling rewrite phase 1. - -2002-01-30 Andreas Fuchs - - * erc.el: * Rework erc-server-PRIVMSG-or-NOTICE - * New function: erc-is-message-ctcp-p - * New function: erc-format-privmessage - * New function: erc-mark-message - * erc-server-PRIVMSG-or-NOTICE: use them. - -2002-01-30 Mario Lang - - * CREDITS, HISTORY: - Initial checkin. - -2002-01-29 Andreas Fuchs - - * erc.el: * erc-put-text-properties: make OBJECT optional - * erc-put-text-property: same - * erc-server-PRIVMSG-or-NOTICE: use them. - * Make erc-display-line-buffer: add the "\n" even when the string would be invisible. - * same: make the \n invisible, too (: - -2002-01-29 Mario Lang - - * erc-ibuffer.el, erc.el: - Rewrote channel tracking using window-configuration-change-hook instead of defadvices. - -2002-01-28 Andreas Fuchs - - * erc-fill.el, erc.el: - * Macro define-erc-highlight-customization: Ease up defining - erc-{fool,pal,..}-highlight-props defcusts. - * defcusts: - - erc-fool-highlight-props - - erc-pal-highlight-props - - erc-dangerous-host-highlight-props - - erc-keyword-highlight-props - - Customizable to either nil or "Hide message". - * erc-string-invisible-p: check for invisible chars in string - * erc-display-line-buffer: use it. - * erc-put-text-properties: put a list of props into a piece of text. - * erc-server-PRIVMSG-or-NOTICE: use it; set appropriate - highlight-props for entire incoming message. This set of changes - allows you to e.g. auto-ignore fools. - -2002-01-28 Mario Lang - - * erc-ibuffer.el: - Added highlight detection support to the Mark column. - Now p, k, f, and d indicate pal, keyword, fool and dangerous-host related activity. - - * erc.el: - Highlight tracking finished. All necessary info should now be in erc-modified-channels. - - * erc.el, erc-ibuffer.el, erc-speedbar.el: - Added highlight tracking to track-modified-channels - no display code yet, the info is just kept in erc-modified-channels - Added erc-modified column to ibuffer - speedbar update - - * erc-ibuffer.el: Added erc-members column - - * erc-ibuffer.el: *** empty log message *** - -2002-01-28 Andreas Fuchs - - * erc-bbdb.el: - * Fix a slight typo. The hook function should be called in - erc-server-376-hook (-: - -2002-01-28 Mario Lang - - * erc-ibuffer.el: *** empty log message *** - -2002-01-27 Mario Lang - - * erc-ibuffer.el: Fixup, it sort of works now. Try it - - * erc-ibuffer.el: Initial version - -2002-01-26 Mario Lang - - * erc.el: *** empty log message *** - -2002-01-25 Andreas Fuchs - - * erc-bbdb.el: * fix two bad things: - - fix the "proc trick": pass proc as an arg through - ...-insinuate-... to ...-show-entry - - hook highlighting into the 376 hook. This one is bound to get - called (-: - * We now only append to hooks only. - * Highlighting of changing records gets updated automatically. - -2002-01-25 Mario Lang - - * erc.el: *** empty log message *** - -2002-01-25 Andreas Fuchs - - * erc-bbdb.el: * nearly complete rewrite of erc-bbdb: - - Removed code duplication in erc-bbdb-NICK and -JOIN. - - Made erc-bbdb-show-entry more general and intelligent. - - erc-bbdb-insinuate-entry is now erc-bbdb-insinuate-and-show-entry - (note the different arglist!): - - erc-search-name-and-create now creates "John Doe" users if name - is not specified. - - No sign of "mail" anywhere anymore. It's all finger-host. (-: - - erc-bbdb-popup-p is now called erc-bbdb-popup-type. - - New customize values: - . erc-bbdb-irc-channel-field channel field name - . erc-bbdb-irc-highlight-field (see below) - . erc-bbdb-auto-create-on-nick-p auto-create record on join - - * Highlighting based on BBDB is now here! Specify which type of - highlighting a person in the BBDB (whose nick you know) and have - fun! Read help to erc-bbdb-init-highlighting for details. Changes: - - new function erc-bbdb-init-highlighting: gets called on server - connect. - - new function erc-bbdb-highlight-record: highlights a person's - nick names. - -2002-01-24 Andreas Fuchs - - * erc-button.el: - * Fix the erc-button-alist regexp for EmacsWiki stuff. delYsid's version - is better (-: - - * erc-button.el: * Added an Ewiki: specifier to the url-regexp. - EmacsWiki: EmacsIRCClient tells you - should highlight "EmacsWiki: EmacsIRCClient" and allow you to - browse to the wiki when the button is activated. - * new custom: erc-emacswiki-url. - * new function: erc-browse-emacswiki: use it. - -2002-01-23 Mario Lang - - * erc-bbdb.el: - erc-bbdb-NICK: Added regexp-quote around fingerhost search. - -2002-01-10 Andreas Fuchs - - * erc.el: - * Channel saving/killing on quit from server implemented: - - defcust erc-save-queries-on-quit: Save server's channel buffers on quitting from server - - defcust erc-kill-queries-on-quit: Kill server's channel buffers on quitting from server - - Macro erc-with-all-buffers-of-server: Run a form inside all the server's query buffers - - Functions erc-{kill,save}-query-buffers: use it. - * Added indent-tabs-mode: t to Local Variables section. - -2002-01-07 Andreas Fuchs - - * erc-replace.el: * fix stupid documentation errors. - -2002-01-07 Mario Lang - - * erc.el: - * (toplevel): Revert previous change. This resulted ina recursive load... - You have to put (require 'erc-button) into your .emacs for now - -2002-01-05 Mario Lang - - * erc.el: - * Added require for erc-button. This is devel. so I need testers :) - - * erc-button.el: * Added proper file headers (GPL). - -2002-01-04 Mario Lang - - * erc-button.el: * erc-button-alist: Added entry for finger - - * erc-button.el: * Removed bogus usage of :button-keymap. - P - Does anyone know what this was supposed to do anyway? - - * erc-button.el: * Initial version. - * This module allows a way of buttonizing text in IRC buffers. - Default it is used for URLs, but other things could be added. - see if you can find another use, erc-button-alist - -2001-12-18 Mario Lang - - * erc.el: * Added missing 747 numreply (banned) - -2001-12-15 Gergely Nagy - - * debian/scripts/install, debian/rules: - updated to 2.1.cvs.20011215-1 - - * debian/changelog: Debian version 2.1.cvs.20011215-1 - -2001-12-11 Andreas Fuchs - - * erc.el: - * applied a nicer version of mhp's patch to remove the last prompt from - saved logs - - * erc-replace.el: * Initial checkin - -2001-12-11 Mario Lang - - * erc.el: - * fixed bug triggered when reuse-buffer was enabled (the default). - Another silly port type problem. Maybe we should unify that once and for all sometimes... - -2001-12-10 Mario Lang - - * erc.el: * erc-message-english: New QUIT and s004 entries. - * (erc-save-buffer-on-part): New variable. - * (erc-kill-buffer-on-part): New variable. - * (erc-server-PART): Use above variables. - * (erc-join-channel): Use DEF argument instead of initial input for completing-read. - -2001-12-08 Tijs van Bakel - - * erc.el: added defcustom erc-nick-uniquifier ^ (i prefer _) - -2001-12-07 Gergely Nagy - - * debian/changelog: changelog for version 2.1.cvs.20011208-1 - -2001-12-07 Tijs van Bakel - - * erc.el: - Added erc-scroll-to-bottom as an erc-insert-hook function. It still bugs a bit, so please test it, thanks - -2001-12-07 Mario Lang - - * erc.el: * Fixed silly bug in erc-server-TOPIC (thanks mhp) - - * erc-speak.el: - * Fix non-greedy matching bug. That one somehow swallowed text - - * erc.el: - Fix Emacs20 problem. For now, we disable erc-track-modified-channels-minor-mode in emacs20 - -2001-12-07 Andreas Fuchs - - * erc-fill.el: - * Fix another stupid one-off error. This time it really works! - (Until I find the next bug. I guess you can hold your breath) (-: - -2001-12-06 Andreas Fuchs - - * erc-fill.el: * Fixed static filling: - ** No more \ed (continued on next line) lines anymore - ** Fixed bug with previous version where longer lines wouldn't get - filled correctly (i.e. at all) - -2001-12-06 Gergely Nagy - - * debian/changelog: changelog for 2.1.cvs.20011206-1 added - -2001-12-06 Andreas Fuchs - - * erc.el: - * Don't discard away status when identifying to NickServ - * Modify `erc-already-logged-in': check for port, too. - - * erc-fill.el: - * Fix stupid loop non-termination error in erc-fill-static when filling - one-line regions. - * Make erc-count-lines return meaningful values - -2001-12-05 Mario Lang - - * erc.el: - * (erc-process-input): Make ' /command' work for quoting /commands - - * erc-speak.el: see changelog - - * erc-fill.el: see erc.el changelog - - * erc.el: - * erc-insert-hook: Changed strategy completely, no start end parameters any more. - We narrow-to-region now, that's much cleaner. - * rename erc-fill-region to erc-fill and change the autoload - ** You'll probably need to restart Emacs - -2001-12-04 Mario Lang - - * erc.el: - * (erc-send-current-line): Fixed long outstanding bug. XEmacs users with erc-fill-region on erc-insert-hook knew that one a long time. - - * erc.el: fix order of attack - - * erc.el: * macroexpanded define-minor-mode for XEmacs - - * erc.el: First try to make channel tracking mouse sensitive - - * erc.el: * More erc-message-format conversion. - erc-format-message-english-PART as an example on how to use functions to format message - * (erc-format-message): Fallback mechanism to use english catalog if variable is not bound - -2001-12-03 Mario Lang - - * erc.el: * (erc-iswitchb): Rewrite, docfix. - Make it use erc-modified-channels as default if available. - - * erc-menu.el: - * Fixage related to erc-track-modified-channels-minor-mode rewrite - - * erc.el: - * (erc-track-modified-channels-minor-mode): Use buffer objects instead of erc-default-target return value for internal state keeping. - - * erc.el: * Made reconnect behave nicer (erc-process-sentinel) - * Rewrote erc-modified-channels-tracking completely. - Its now a minor mode (erc-track-modified-channels-minor-mode) - It uses a list as internal representation now, so all silly string-parsing - related bugs should be gone. - Use (erc-track-modified-channels-minor-mode t) now to toggle this functionality. - Don't set the erc-track-modified-channels-minor-mode variable yourself, use the toggle function - -2001-11-29 Gergely Nagy - - * debian/changelog: final version - -2001-11-29 Mario Lang - - * erc.el: - * (erc-channel-p): Make it work with string and buffer as parameter. buffer. - * (erc-format-message): Add a check for functionp. This allows a format-specifier also to be a function name, which gets called with args applied and needs to return the actual format string. - * Converted some formats, JOIN, JOIN-you, MODE, ... - -2001-11-28 Mario Lang - - * erc.el: - * (erc-prepare-mode-line-format): Added sanity checks to prevent it from having problems with server buffers where the connection failed - - * erc-bbdb.el: - * (erc-bbdb-JOIN): regexp-quote the fingerhost before searching, some people have really strange characters as their user names - - * erc.el: Remove a stupid debug like (message ...) call - -2001-11-28 Gergely Nagy - - * debian/changelog: draft of 2.1.cvs.20011128-1 - - * debian/rules: simplify for the all-in-one erc package - - * debian/control: integrated erc-speak back into erc - - * debian/maint/conffiles, debian/maint/conffiles.in, debian/maint/postinst, - debian/maint/postinst.in, debian/maint/prerm, debian/maint/prerm.in, - debian/scripts/install, debian/scripts/install.in, debian/scripts/remove, - debian/scripts/remove.in, debian/scripts/startup.erc-speak: - since erc-speak is gone, resurrect the static files, and update them to support the latest erc - -2001-11-28 Mario Lang - - * erc.el: * (erc-mode): Shouldn't be interactive. - * (erc-info-mode): Ditto. - - * erc.el: * (erc-server-352): Added hopcount parsing. - Added call to erc-update-channel-member to fill in channel-members information - on /WHO if the channel is joined. - -2001-11-27 Mario Lang - - * erc-speedbar.el: *** empty log message *** - - * erc-speedbar.el: * (erc-speedbar-expand-user): New function. - Used when more information than just the nick name is available about a dude. - - * erc.el: * Fixed stupid edit,checkin,save cycle error :) - - * erc.el: - * (erc-generate-log-file-name-default): Renamed to -long - Doc fix. - * (erc-generate-log-file-name-old): Renamed to -long - Doc fix. - * (erc-generate-log-file-name-function): Set default to ...-long - Doc fixes - - * erc-speedbar.el: *** empty log message *** - -2001-11-26 Mario Lang - - * erc-speedbar.el: * Integrated channel names list - what else do we need to replace info buffers??? - please test that code and comment on erc-ehlp, thanks - - * erc-speedbar.el: - * Added erc-speedbar-goto-buffer and therefore enable switching to the buffers from speedbar - - * erc-speedbar.el: - I had to check this in, it works !! sort of,, megaalphagammaversion, first version. test, play, submit ideas/patches - -2001-11-26 Gergely Nagy - - * erc.el(erc-mode): moved erc-last-saved-position here - moved buffer naming code from here.. - (erc): ...to here - (erc-generate-log-file-name-old): only prepend target if it exists - - made erc-log-insert-log-on-open a defcustom - -2001-11-26 Mario Lang - - * erc.el: - * Applied antifuchs/mhp patches, the latest on erc-help, unmodified - * New variable: erc-reuse-buffers default to t. - * Modified erc-generate-new-buffer-name to use it. it checks if server and port are the same, - then one can assume that's the same channel/query target again. - -2001-11-23 Mario Lang - - * erc-bbdb.el: - * new function erc-BBDB-NICK to handle nickname annotation on a nick-change event of a known record - - * erc.el: * Remove erc-rename-buffer, its no longer necessary - * Remove erc-autoop-*. it was broken, and needed rewrite anyway - * write erc-already-logged-in in terms of erc-buffer-list and make the duplicate login check work again - - * erc.el: * Fixed stupid typo - -2001-11-22 Mario Lang - - * erc.el: * New local variable, erc-announced-server-name - * erc-mode-line-format supports a new symbol, target-and/or-server - * The mode-line displays the announced server name now (for autojoin later..., - greets Adam) - * New macro, erc-server-hook-list for a nice way to define the defcustoms of the erc-server-*-hook's - Thanks go to the guy from #emacs who helped with that - * erc-fill-region is now autoloaded from erc-fill.el - * erc-fill.el implements a new fill method, erc-fill-static - (setq erc-fill-function 'erc-fill-static) - * Some other things I forgot right now - - * erc-bbdb.el: *** empty log message *** - - * erc-fill.el: Initial version. - - * erc-complete.el: - Applied antifuchs patch to make completion work with (string= erc-prompt "") - - * erc-complete.el: - added function erc-nick-completion-exclude-myself - you can set erc-nick-completion to 'erc-nick-completion-exclude-myself to use it - -2001-11-21 Mario Lang - - * erc-bbdb.el: - * Changed usage of 'finger-host to bbdb-finger-host-field - - * erc-bbdb.el: - * Changed WHOIS to use finger-host instead of net field. - * Added 'visible as option to erc-bbdb-popup-p to only pop-up the bbdb buffer if a join happened in a visible buffer on any visible frame. - * Added (regexp-quote ...) for nickname search in erc-bbdb-JOIN - -2001-11-20 Mario Lang - - * erc-bbdb.el: * Added JOIN support - -2001-11-19 Mario Lang - - * erc.el: - Initial message catalog code. converted erc-action-format usage to use it - - * erc.el: * erc-play-sound: Added XEmacs related check - - * erc-bbdb.el: * Initial version, many thanks to Andreas Fuchs - - * erc.el: * Fixed silly problem with whois/was handling - - * erc.el: * Renamed prev-rd to erc-previous-read - * Removed erc-next-line-add-newlines and s next-line-add-newlines to nil in defun erc by default - - * erc.el: - fixed xemacs compatibility prob with delete, thanks Adam - -2001-11-18 Mario Lang - - * erc.el: numreplies 301 & 461 - -2001-11-13 Tijs van Bakel - - * erc.el: - Added code for error reply 421 "Unknown command", to test the new server parsing system. - This was really easy! Thanks ZenIRC guys & delysid :-) - -2001-11-13 Mario Lang - - * erc.el: * Allow connecting to SSL enabled irc servers. - Ugly hack, but it works for now. Be sure to use the numeric irc port 994 so that erc can recognize what you want - good example is - irc server: ircs.segfault.net - port: 994 - - meet me there, I am still delYsid :) - - * erc.el: * some more numreply handlers - * cleanup in erc-process-away-p - * new function erc-display-error-notice - - * erc.el: * numreply 501 and 221 - - * erc.el: - removed obsolete old hook variables. Your functions may break, but it is easy to hook them up to the new hooks. - erc-part-hook: use erc-server-PART-hook instead - erc-kick-hook: use erc-server-KICK-hook instead - and so on - - * erc.el: - fixed serious bug which cause privmsgs vanishing when erc-auto-query was set to nil - - * erc.el: cleaned up erc-process-filter - - * erc.el: * 401 and 320 numreplies implemented - - * erc.el: * Removed old/now obsolete code - - * erc.el: * Fixed bug in erc-server-MODE - -2001-11-12 Mario Lang - - * erc.el: fixed it - - * erc.el: - *** We switched over. New server message parsing/handling is running now. Thanks to the zenirc developers for the great ideas I got from the code!!!!! Go and test it, poke at it, bug me on irc about problems - - * erc.el: *** empty log message *** - -2001-11-12 Tijs van Bakel - - * erc.el: - Fixed bug in erc-get-buffer, now channel names are compared in - a case-insensitive way. - -2001-11-12 Mario Lang - - * erc.el: erc-server-353 - -2001-11-12 Tijs van Bakel - - * erc.el: Fixed docstring for erc-get-buffer. - Added erc-process to a lot of calls to erc-get-buffer, so - that only the local process is searched. - -2001-11-12 Mario Lang - - * erc.el: * erc-buffer-filter: do it differently - - * erc.el: ugly but working fix for mhp's query problem - - * erc.el: * erc-server-PRIVMSG-or-NOTICE - Now, all the server word replies are finished. Going to numreplies now - - * erc.el: - * debugging facilities for the transition. C-x 2 C-x o M-x ielm RET erc-server-vectors RET ; to get a list of all server messages currently not handled in the new code. Feel free to pick one and implement it - - * erc.el: * erc-server-KICK and erc-server-TOPIC. new functions - * erc-server-305-or-306 and erc-server-311-or-314 - - * erc.el: - * ported PART and QUIT msgs to the new scheme, many to go. but it is a easy task. does someone wanna try and start with numreplies? - - * erc.el: * erc-server-JOIN - - * erc.el: * Ported erc-server-INVITE code - - * erc.el: * erc-server-ERROR and erc-server-MODE - -2001-11-11 Mario Lang - - * erc.el: * zen - - * erc.el: * New variable erc-connect-function. - - * erc.el: - * New function erc-channel-p and use it where appropriate - - * erc.el: * Removed the variable erc-buffer-list completely now - * Moved erc-dbuf around a bit - - * erc.el: * Fix silly change in quit/rename msg handling - - * erc.el: thanks mhp, fixed - - * erc.el: * Tijs van Bakel's work from 10th Nov. merged in - * My additions to that idea merged in too - Basically, this is a major rewrite, if you are scared and want avoid problems, - stay at your current version. It seems fairly stable though. - That changed? erc-buffer-name handling was completely rewritten, - and erc-buffer-list local variable handling removed. - Simplifies a lot of code. Poke at it. Read the diff. Report - bug/send patches! - - * erc.el: * Added variable listing when /set is used without args - -2001-11-10 Mario Lang - - * erc.el: - * Comment/structure cleanup, removal of unnecessary code - - * erc.el: only some code beautification - - * erc-imenu.el: - remove add-hook call, that's done in erc.el now for autoloadability - - * erc.el: * Make erc-imenu autoloadable - - * erc.el: - * The long promised erc-mode-line-format handling rewrite - Poke at it, try it, play with it, report bugs - - * erc.el: - some regex-quote fixes, new function erc-cmd-set, and minor things - -2001-11-08 Mario Lang - - * erc.el: - * added second timestamp-format (erc-away-timestamp-format) for marking msgs when being away - - * erc-complete.el: fixed silly defun - - * erc.el: * Rewrote erc-load-irc-script (simplified) - * Removed deprecated code - - * erc-speak.el: * reflect changes in erc.el - - * erc.el: - * Moved completion related functions into erc-complete.el - placed an autoload instead into erc.el. That quite cool, - because erc-complete.el only gets loaded when you use - TAB first time in erc. - - * erc-complete.el: _ Initial checkin - - * erc.el: * New function: erc-chain-hook-with-args - * Changed calls to erc-insert-hook to use it - -2001-11-07 Mario Lang - - * erc.el: * Patch from Fabien Penso - Make completion case insensitive. try it! its cool - - * erc.el: * Reduction patch 2 - This time, we move the input ring handling into erc-ring.el - Remember that you need (require 'erc-ring) in your .emacs to get the input handling as a feature - And remember, that you don't need it if you don't use input ring :-) - - * erc-ring.el: * Initial checkin - - * erc.el: * The great reduction patch :-) - moved relevant function from erc.el to new file erc-menu.el and erc-imenu.el - - * erc-imenu.el: Initial version - - * erc-menu.el: * Initial version - - * erc.el: * wording change suggested by Benjamin Drieu - -2001-11-07 Tijs van Bakel - - * erc.el: Added Emacs version to /SV - -2001-11-07 Mario Lang - - * erc.el: * Hookification patch, read the diff - - * erc.el: too tired for a changelog :) - -2001-11-06 Mario Lang - - * erc.el: - * make erc-cmd-op and erc-cmd-deop take multiple nicknames as argument - -2001-11-06 Gergely Nagy - - * debian/changelog: sync - - * debian/rules: fixed a typo: PKGDIR, not PKIDR - -2001-11-06 Mario Lang - - * erc.el: - * Changed timestamping when away to use erc-timestamp-format and append the timestamp instead of prepending it.. - * minor cleanup, s/(if (not /(unless/ and the like - -2001-11-06 Tijs van Bakel - - * erc.el: Fixed OP and DEOP commands to return T. - Added SV say-version command. - Added erc-send-message utility function, but it's not used everywhere yet. - -2001-11-05 Mario Lang - - * erc.el: stupid delYsid, forgot require 'format-spec. good nite - - * erc.el: - * new variable erc-action-format. Some erc-notice-prefix fixes again - - * erc.el: * erc-minibuffer-privmsg defaults to t - - * erc.el: - * Small fix in relation to the transition to erc-make-notice - -2001-11-05 Tijs van Bakel - - * erc.el: - Renamed erc-message-notices to erc-minibuffer-notice, and renamed erc-prevent-minibuffer-privmsg to erc-minibuffer-privmsg, inverting its functionality - - * erc.el: Added support for channel names starting with & + and !. - Also, many changes partially discussed on the mailing list: - - * erc.el (cl): Add requirement for cl package. - (erc-buffer-list): Make this variable global again. - (erc-default-face): Fix typo. - (erc-timestamp-face): Add face for timestamps. - (erc-join-buffer, erc): Add a 'bury option. - (erc-send-action): Add timestamp. - (erc-command-table): Add /CLEAR, /DEOP, /OP, /Q. - (erc-send-current-line): Add timestamp. - (erc-send-current-line): Add call to erc-insert-hook. - (erc-cmd-clear): New command to clear buffer contents. - (erc-cmd-whois): Fix cut'n'paste-o. - (erc-cmd-deop): New command to deop a user. - (erc-cmd-op): New command to op a user. - (erc-make-notice): Moved a lot of duplicate code here. Perhaps - this should also be done for erc-highlight-error. - (erc-parse-line-from-server): Now NOTICE will also open a new - query, just as PRIVMSG. - (erc-parse-line-from-server): Call erc-put-text-property on a - channel message/notice first, before concatenating nick and - timestamp &c. - (erc-message-notices): Add option to display notices in - minibuffer. - (erc-fill-region): No longer strip spaces in front of incoming - messages. - (erc-parse-current-line): No longer strip spaces in front of text - input by user. - - Hopefully I didn't break too much :( - -2001-11-05 Mario Lang - - * erc.el: - * New function erc-nickserv-identify-autodetect for erc-insert-hook. Added by default currently. - - * erc.el: - * Mini-fix in erc-process-num-reply (= n 353): Added @ as prefix character to make certain channels on opn work again nicely - -2001-10-31 Gergely Nagy - - * debian/changelog: updated to reflect changes - - * debian/scripts/install.in: - moved #PKGFLAG# before -f batch-byte-compile - -2001-10-29 Mario Lang - - * erc.el: - Imenu fixed somehow, added IRC services interactive function for identify to NickServ. Read the diff - -2001-10-26 Gergely Nagy - - * debian/changelog: sigh. -2 - -2001-10-25 Gergely Nagy - - * debian/changelog: updated to reflect changes - - * debian/rules: handle conffiles.in too - - * debian/maint/conffiles.in: new file - - * debian/maint/conffiles: superseded by conffiles.in - - * debian/scripts/startup: superseded by startup.erc - -2001-10-25 Mario Lang - - * debian/scripts/startup.erc-speak: * Initial version - - * debian/scripts/startup.erc: * Added and fixes minimal typo - -2001-10-25 Gergely Nagy - - * debian/changelog: updated to reflect changes - - * debian/rules: - modified to be able to build the erc-speak package too - - * debian/control: added the new erc-speak package - - * debian/README.erc-speak, debian/maint/postinst.in, debian/maint/prerm.in, - debian/scripts/install.in, debian/scripts/remove.in: - new file - - * debian/maint/postinst, debian/maint/prerm, debian/scripts/install, - debian/scripts/remove: - removed, superseded by its .in counterpart - -2001-10-25 Mario Lang - - * erc.el: * Fixed some defcustom :type 's - * Added erc-before-connect hook which gets called with server port and nick. - Use this hook to e.g. setup a tunnel before actually connecting. - something like (when (string= server "localhost") ...) - -2001-10-24 Mario Lang - - * erc.el: * Patch by smoke: fix erc-cmd-* commands and add aliases - -2001-10-23 Mario Lang - - * erc-speak.el: - * Added a new personality for channel name announcement, This makes streams of flooded channels much easier to listen to, - especially if you are on more than one channel simultaneously. - - * erc.el: - * Made the completion postfix customizable through erc-nick-completion-postfix - - * erc-speak.el, erc.el: - * Added erc-prevent-minibuffer-privmsg - - * erc-speak.el: - * Quickish hack to allow exclusion of timestamps from speaking. see erc-speak-filter-timestamps - -2001-10-21 Mario Lang - - * erc-speak.el: - * Removed now really obsolete code. Package size reduced by 50% - - * erc-speak.el: - * Very important fix! Now erc-speak is really complete. Messages don't get cut anymore. Be sure to use auditory icons, - it's really cool now!!! - - * erc-speak.el: *** empty log message *** - - * erc-speak.el: * Major simplification. depends on my 2001-10-21 changes to erc.el. - * Things removed, read diff - -2001-10-21 Gergely Nagy - - * debian/changelog: oops, silly typo - - * debian/changelog, debian/control, debian/copyright, - debian/maint/conffiles, debian/maint/postinst, debian/maint/prerm, - debian/rules, debian/scripts/install, debian/scripts/remove, - debian/scripts/startup: - initial check-in - -2001-10-21 Mario Lang - - * erc.el: - * Changed erc-insert-hook to get two arguments, START and END of the region - which got inserted. CAREFUL! This could break stuff, but it makes the hook - much more usable. - - * erc.el: - * Made erc-smiley a new option, currently set to t to showoff this feature. :) - -2001-10-20 Mario Lang - - * erc.el: * Add missing erc-mode-hook variable - * Add smiley-support (preliminary test) - -2001-10-20 Alex Schroeder - - * erc.el: - Replaced all occurrences of put-text-property with a call to - erc-put-text-property. - (erc-put-text-property): New function. - (erc-tracking-modified-channels): Moved to the front of the file such - that it is already defined when the menu is being defined. - (erc-modified-channel-string): Ditto. - -2001-10-18 Alex Schroeder - - * erc.el: Removed some commentary. The wiki page is the place to - put such information. - (erc-fill-prefix): Doc change. - (erc-notice-highlight-type): Doc change, now a user option. - (erc-pal-highlight-type): Doc change, now a user option. - (erc-fool-highlight-type): New option. - (erc-keyword-highlight-type): New option. - (erc-dangerous-host-highlight-type): New option. - (erc-uncontrol-input-line): Doc change. - (erc-interpret-controls-p): Doc change, now a user option. - (erc-multiline-input): Doc change. - (erc-auto-discard-away): Doc change. - (erc-pals): Changed from string to regexp. - (erc-fools): New option. - (erc-keywords): Renamed from erc-highlight-strings. WATCH OUT: - Not backwards compatible change! - (erc-dangerous-hosts): Renamed from erc-host-danger-highlight. - WATCH OUT: Not backwards compatible change! - (erc-menu-definition): Added menu entries for fools, keywords and - dangerous hosts. - (erc-mode-map): Changed keybindings from C-c to - various C-c combinations. - (erc-dangerous-host-face): Renamed from erc-host-danger-face. - WATCH OUT: Not backwards compatible change! - (erc-fool-face): New face. - (erc-keyword-face): Renamed from erc-highlight-face. WATCH OUT: - Not backwards compatible change! - (erc-parse-line-from-server): Fixed highlighting in the cases - where (equal erc-pal-highlight-type 'all), added code to handle - erc-fool-highlight-type, erc-dangerous-host-highlight-type - (erc-update-modes): Replaced erc-delete-string with delete. - (erc-keywords): Renamed from erc-highlight-strings, handle - erc-keyword-highlight-type. - (erc-delete-string): Removed. - (erc-list-match): New function. - (erc-pal-p): Use erc-list-match. - (erc-fool-p): New function. - (erc-keyword-p): New function. - (erc-dangerous-host-p): Renamed from erc-host-danger-p, use - erc-list-match. - (erc-directed-at-fool-p): New function. - (erc-add-entry-to-list): New function. - (erc-remove-entry-from-list): New function. - (erc-add-pal): Use erc-add-entry-to-list. - (erc-delete-pal): Use erc-remove-entry-from-list. - (erc-add-fool): New function. - (erc-delete-fool): New function. - (erc-add-keyword): New function. - (erc-delete-keyword): New function. - (erc-add-dangerous-host): New function. - (erc-delete-dangerous-host): New function. - -2001-10-07 Mario Lang - - * erc.el: * irc vs ircd default port fixed - - * erc.el: * Added topic-change to imenu - - * erc.el: * More imenu spiffyness - - * erc.el: * Added imenu support - - * erc.el: - * Fix to /topic to show topic instead of setting it to null :) - -2001-10-05 Mario Lang - - * erc.el: * First version of erc-rename-buffer - - * erc.el: * more header-line tricks. - - * erc.el: - * Small fix to do erc-update-mode-line-buffer in erc-update-channel-topic - - * erc.el: * Added erc-header-line-format - -2001-10-04 Mario Lang - - * erc.el: * mini-fix, add msgp to auto-query code - - * erc.el: * Added command-names to completion (erc-command-table) - * New variable erc-auto-query. When set, every arriving message to you - will open a query buffer for that sender if not already open. - * Compatibility function for non-existing line-beginning|end-position functions in XEmacs. - -2001-10-03 Mario Lang - - * erc.el: - * Removed a lot of (progn ...) where they were not necessary - * Changed some (if ...) without else part to (when ...) - * Some (while ...) to use (dolist ...) - * Fix for completion popup generating tracebacks. - * New function erc-arrange-session-in-multiple-windows - * Lots of other stuff, read the diff - -2001-10-02 Mario Lang - - * erc.el: * Added erc-kill-input and keybinding C-c C-u for it - -2001-10-01 Mario Lang - - * erc.el: * Another fix to nick-completion - * Additional checks in erc-track-modified-channels - -2001-09-26 Mario Lang - - * erc.el: * Fixed completion (alex) - * Now popup buffer doesn't destroy your window configuration. - * Fixed away handling (incomplete) - -2001-09-24 Mario Lang - - * erc.el: Fixed silly quoting-escape error - -2001-09-23 Mario Lang - - * erc.el: * Added auto-op support (unfinished) - * Added erc-latest-version. - * Added erc-ediff-latest-version. - -2001-09-21 Mario Lang - - * erc.el: - * Minor menu additions (invite only mode is now a checkbox) - -2001-09-20 Mario Lang - - * erc.el: - * Fix (erc-cmd-names): This should fix C-c C-n too, hopefully it was the right fix and doesn't break anything else. - - * erc.el: * Fixes XEmacs easymenu usage (2nd time). - -2001-09-19 Mario Lang - - * erc.el: - * (erc-complete-nick): Add ": " only if one completes directly after the erc-prompt, otherwise, add just one space - - * erc.el: - * Changed menu-definition to use easymenu (hopefully this now works under XEmacs) - * Fix for custom problem with :must-match on XEmacs (thanks shapr) - * Added /COUNTRY command using (what-domain) from package mail-extr (shapr) - * Fix for case-sensitivity problem with pals (they are now all downcased) - * Different (erc-version) function which now can take prefix argument to insert the version information into the current buffer, - instead of just displaying it in the minibuffer. - -2001-09-10 Mario Lang - - * erc.el: Updated erc-version-string - - * erc.el: Version number change and last read-through... - -2001-09-04 Mario Lang - - * erc.el: Added some asterisks - -2001-08-24 Mario Lang - - * erc.el: - Fixed hidden channel buffer tracking (sort of), now using switch-to-buffer for advice. - This version is unofficially named 2.1prebeta1. Please test it and send - fixes to various problems you may encounter so that we can eventually - release 2.1 soon. - -2001-08-14 Mario Lang - - * erc.el: - Added function erc-bol and keybinding C-c C-a for it (contributed by Benjamin Rutt - - * erc.el: - Checked in lathis code and modified it slightly. Still unsure about set-window-buffer advice, current attempt doesn't seem to work. - Removed (nick -> #channel) from mode-line. (CLOSED) and (AWAY...) should still be displayed when appropriate - -2001-08-06 Mario Lang - - * erc.el: - added local-variable channel-list in session-buffers and make /LIST use it. - erc-join-channel can now do completion after /LIST was executed - -2001-08-05 Mario Lang - - * erc.el: Tweaked erc-join-channel and erc-part-from-channel - -2001-07-27 Mario Lang - - * erc.el: some more defcustom stuff - - * erc.el: Patch from Henrik Enberg : - Adds variables erc-frame-alist and erc-frame-dedicated-p. - - * erc.el: fixed erc-part-from-channel - - * erc.el: - fixed match-string problem and added interactive topic setting function. - - * erc.el: fixed silly string-match bug - - * erc.el: - Added erc-join-channel and erc-part-from-channel (interactive prompts), as well as keybindings. C-c C-j #emacs RET is now enough :) - -2001-07-27 Alex Schroeder - - * erc.el(erc-display-line-buffer): Simplified filling. - (erc-fill-region): New function. - -2001-07-27 Mario Lang - - * erc.el: Added redundancy check in output - -2001-07-26 Alex Schroeder - - * erc.el(erc-send-action): Add text-property stuff. - (erc-input-action): Removed text-property stuff. - (erc-command-table): Corrected command for DESCRIBE. Still - doesn't work though. No idea what it should do. Looks like a no op. - (erc-cmd-me): Doc change. - -2001-07-26 Mario Lang - - * erc.el: - fixed one occurrence of a setq with only one argument (XEmacs didn't like that) - - * erc.el: - Added erc-next-line-add-newlines customization possibility. - - * erc.el: - added erc-fill-prefix for defining your own way of filling and fixed filling somehow - - * erc.el: - fixed small incompatibility in erc-parse-line-from-server at (and (= n 353) regexp - -2001-07-25 Mario Lang - - * erc.el: - Added erc-filling and filling code to erc-display-line-buffer. - -2001-07-08 Alex Schroeder - - * erc.el(try-complete-erc-nick): Make the ": " part of the - expansion - - * erc.el: require ring - -2001-07-08 Mario Lang - - * erc.el: *** empty log message *** - -2001-07-07 Mario Lang - - * erc.el: typo - - * erc.el: omit - -2001-07-06 Alex Schroeder - - * erc.el(erc-mode): Call erc-input-ring-setup. - (erc-send-current-line): Call erc-add-to-input-ring. - (erc-input-ring): New variable. Currently not buffer local. - (erc-input-ring-index): New variable. Currently not buffer local. - (erc-input-ring-setup): New function. - (erc-add-to-input-ring): New function. - (erc-previous-command): New function. - (erc-next-command): New function. - (erc-mode-map): Uncommented keybindings for erc-next-command and - erc-previous-command. - -2001-07-05 Alex Schroeder - - * erc.el(erc-highlight-strings): Removed debug message. - - * erc.el(erc-join-buffer): Changed default to 'buffer. - (erc-join-info-buffer): Changed default to 'disable. - (erc-nick-completion): Changed default to 'all. - -2001-07-03 Alex Schroeder - - * erc.el(erc-highlight-strings): New option and new function. - (erc-parse-line-from-server): Use it. - Various empty lines removed. Various doc strings fixed. - - * erc.el: Removed more empty lines. - - * erc.el(erc-member-string): replaced by plain member - Otherwise, lots of deleting of empty lines... I'm not too happy with that - but I feel better when the code is "cleaned up". - -2001-07-03 Mario Lang - - * erc.el: Ugly hack, but looks nicer when giving commands - - * erc-speak.el: ugly hack, but looks nicer now - -2001-07-03 Alex Schroeder - - * erc.el(try-complete-erc-nick): New function. - (erc-try-complete-nick): New function. - (erc-nick-completion): New option. - (erc-complete): Call hippie-expand such that erc-try-complete-nick - will be called eventually. Based on erc-nick-completion - try-complete-erc-nick will then complete on the nick at point. - -2001-07-02 Mario Lang - - * erc.el: - Insert (erc-current-nick) instead of (erc-display-prompt). good night :) - - * erc.el: - small, but it was annoying, so I just did it (defcustom for erc-join-buffer and erc-join-info-buffer) - -2001-06-29 Alex Schroeder - - * erc.el: Use defface to define all faces. - Removed some history from the commentary, as well as some other - commentary editing. - -2001-06-28 Mario Lang - - * erc.el: hmm, defcustom for erc-user-full-name - - * erc-speak.el, erc.el: *** empty log message *** - -2001-06-27 Mario Lang - - * erc.el: typo - - * erc.el: Some more defcustom - - * erc-speak.el: nothing, really - -2001-06-26 Mario Lang - - * erc.el: Some defcustom stuff. Still no defgroup though :) - - * erc.el: - Initial change to erc.el (2.0). Mainly list of ideas and features - and syntax-table entries. - - * erc-speak.el, erc.el: Initial Import - - * erc-speak.el, erc.el: New file. - - Copyright (C) 2001-2025 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 3 of the License, 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. If not, see . - -;; Local Variables: -;; coding: utf-8 -;; add-log-time-zone-rule: t -;; End: diff --git a/lisp/erc/ChangeLog.2 b/lisp/erc/ChangeLog.2 deleted file mode 100644 index c3c301b9a6f..00000000000 --- a/lisp/erc/ChangeLog.2 +++ /dev/null @@ -1,780 +0,0 @@ -2015-11-07 Kelvin White - - * erc-pcomplete.el (pcomplete-erc-nicks): Fix bug for tab complete - (bug#18771) - -2015-03-25 Stefan Monnier - - * erc.el (erc-switch-to-buffer): Fix last change (bug#20187). - -2015-03-16 Stefan Monnier - - * erc.el (erc-switch-to-buffer): Rename from erc-iswitchb and rewrite - using read-buffer (bug#20116). - (erc--buffer-p): New function, extracted from erc-buffer-filter. - (erc-buffer-filter): Use it. - (erc-with-all-buffers-of-server): Silence compile warning if the return - value is unused. - (erc-is-valid-nick-p, erc-common-server-suffixes, erc-get-arglist) - (erc-command-name, erc-popup-input-buffer): Use \` and \' to match - beg/end of string. - -2015-03-03 Kelvin White - - * erc.el: Add old version string back to file header for - package.el compatibility - -2015-03-03 Glenn Morris - - * erc.el (erc-rename-buffers): Doc fix. Add :version. - -2015-03-03 Dima Kogan - - * erc-backend.el (define-erc-response-handler): Give hook-name - default value of nil and add-to-list (bug#19363). -2015-02-14 Stefan Monnier - - * erc-spelling.el (erc-spelling-init): - Use flyspell-generic-check-word-predicate. - -2015-01-28 Dima Kogan - - * erc-backend.el (define-erc-response-handler): Give hook-name - default value of nil and add-to-list (bug#19363). - -2015-01-22 Paul Eggert - - Don't downcase system diagnostics' first letters - * erc-dcc.el (erc-dcc-server): Ignore case while comparing diagnostics. - -2014-11-23 Michael Albinus - - * erc-desktop-notifications.el (erc-notifications-bus): - New customer option. Supports cases when Emacs hasn't been - invoked in the same environment where the notifications shall go to. - (erc-notifications-notify): Use it. - -2014-11-10 Kelvin White - - * erc-stamp.el (erc-timestamp-intangible): Change version tag to 24.5. - -2014-11-05 Stefan Monnier - - * erc.el (erc-send-input): Bind `str' dynamically (bug#18936). - -2014-10-29 Paul Eggert - - Simplify use of current-time and friends. - * erc-backend.el (TOPIC): Omit unnecessary call to current-time. - * erc.el (erc-emacs-time-to-erc-time): Simplify by using float-time. - (erc-current-time): Simplify by using erc-emacs-time-to-erc-time. - -2014-10-20 Glenn Morris - - * Merge in all changes up to 24.4 release. - -2014-10-15 Ivan Shmakov - - * erc-track.el (erc-modified-channels-display): Update mode line - more frequently (bug#18510). - -2014-10-10 Kelvin White - - * erc.el (erc-initialize-log-marker): Only initialize - erc-last-saved-position if not already a marker. - -2014-10-04 Stefan Monnier - - * erc.el (erc-channel-receive-names): Silence compiler warning. - (erc-format-@nick, erc-update-modes): Idem. - -2014-10-03 Kelvin White - - * erc.el (erc-rename-buffers): Use defcustom instead of defvar for - buffer renaming configuration option. - -2014-10-02 Paul Eggert - - * erc.el (erc-nick-at-point): Fix format-string typo (Bug#17755). - -2014-10-02 Kelvin White - - * erc.el (erc-rename-buffer-p): When set to t buffers will be - renamed to the current irc network. - (erc-format-target-and/or-network): Use `erc-rename-buffer-p' when - renaming buffers. - - * erc-ring.el (erc-input-ring-setup): Fixes Bug #18599 - -2014-09-30 Stefan Monnier - - * erc-track.el (erc-modified-channels-display): Update all mode lines - if needed (bug#18510). Remove call to erc-modified-channels-object - where we ignored the return value. - (erc-modified-channels-update): Don't force-mode-line-update here - any more. - -2014-09-26 Kelvin White - - * erc.el (erc-format-nick): Fix code regression - Bug #18551 - -2014-09-25 Kelvin White - - * erc.el: Follow Emacs version instead of tracking it separately. - (erc-quit/part-reason-default) : Clean up quit/part message - functions by abstracting repetitive code, change version string. - (erc-quit-reason-various, erc-quit-reason-normal, erc-quit-reason-zippy) - (erc-part-reason-normal, erc-part-reason-zippy, erc-part-reason-various) - (erc-cmd-SV, erc-ctcp-query-VERSION, erc-version, erc-version-string): - Change version string. - -2014-08-13 Kelvin White - - * erc.el (erc-send-input): Disable display commands in current buffer - (erc-format-target-and/or-network): Fix cases when buffer name is set - -2014-08-12 Stefan Monnier - - * erc-stamp.el (erc-timestamp-intangible): Disable by default because - `intangible' is evil. - -2014-08-07 Kelvin White - - * erc.el (erc-channel-receive-names): Fix variable names - (erc-format-target-and/or-network): Rename server-buffers to - network name if possible - -2014-07-08 Stefan Monnier - - * erc.el (erc-channel-receive-names): Reduce redundancy. - -2014-06-19 Kelvin White - - * erc-backend.el: Handle user modes in relevant server responses - * erc.el: Better user mode support. - (erc-channel-user): Add members for new modes. - (erc-channel-member-halfop-p, erc-channel-user-admin-p) - (erc-channel-user-owner-p): Use new struct members. - (erc-format-nick, erc-format-@nick): Display user modes as nick prefix. - (erc-nick-prefix-face, erc-my-nick-prefix-face): Add new faces - (erc-get-user-mode-prefix): Return symbol for mode prefix. - (erc-update-channel-member, erc-update-current-channel-member) - (erc-channel-receive-names): Update channel users. - (erc-nick-at-point): Return correct user info. - -2014-04-04 Stefan Monnier - - * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): Simplify. - (erc-load-script): Tighten a regexp. - -2014-02-25 Julien Danjou - - * erc-networks.el (erc-determine-network): Check that NETWORK as a - value, some servers set it to nothing. - -2014-01-31 Glenn Morris - - * erc.el (erc-accidental-paste-threshold-seconds): Doc tweak. - -2014-01-25 Rüdiger Sonderfeld - - * erc.el (erc): Link to info manual. - -2013-12-28 Glenn Morris - - * erc-log.el (erc-log-file-coding-system): Specify custom type. - -2013-11-25 Glenn Morris - - * erc-button.el (erc-nick-popup): Make `nick' available in the - eval environment. (Bug#15969) - -2013-11-04 Stefan Monnier - - * erc-pcomplete.el (erc-pcomplete): Set this-command. - -2013-09-21 Glenn Morris - - * erc.el (erc-invite-only-mode, erc-toggle-channel-mode): - Remove unused local variable `erc-force-send'. - -2013-09-19 Glenn Morris - - * erc-button.el (erc-button-click-button, erc-button-press-button): - * erc-list.el (erc-list-handle-322): - Mark unused arguments. - - * erc.el (erc-open-server-buffer-p): Actually use the `buffer' arg. - * erc-backend.el (erc-server-process-alive): Take optional `buffer' arg. - -2013-09-18 Glenn Morris - - * erc-button.el (erc-button-add-buttons): Remove unused local vars. - -2013-09-14 Vivek Dasmohapatra - - * erc.el (erc-update-mode-line-buffer): - Handle absent topic. (Bug#15377) - -2013-09-13 Glenn Morris - - * erc-desktop-notifications.el (dbus-debug): Declare. - -2013-08-22 Stefan Monnier - - * erc.el: Use lexical-binding. - (erc-user-full-name): Minor CSE simplification. - (erc-mode-map): Assume command-remapping is available. - (erc-once-with-server-event): Replace `forms' arg with a function arg. - (erc-once-with-server-event-global): Remove. - (erc-ison-p): Adjust to change in erc-once-with-server-event. - (erc-get-buffer-create): Remove arg `proc'. - (iswitchb-make-buflist-hook): Declare. - (erc-setup-buffer): Use pcase; avoid ((lambda ..) ..). - (read-passwd): Assume it exists. - (erc-display-line, erc-cmd-IDLE): Avoid add-to-list, adjust to change - in erc-once-with-server-event. - (erc-cmd-JOIN, erc-set-channel-limit, erc-set-channel-key) - (erc-add-query): Minor CSE simplification. - (erc-cmd-BANLIST, erc-cmd-MASSUNBAN): Adjust to change - in erc-once-with-server-event. - (erc-echo-notice-in-user-and-target-buffers): Avoid add-to-list. - * erc-track.el: Use lexical-binding. - (erc-make-mode-line-buffer-name): Use closures instead of `(lambda...). - (erc-faces-in): Avoid add-to-list. - * erc-notify.el: Use lexical-binding. - (erc-notify-timer): Adjust to change in erc-once-with-server-event. - (erc-notify-QUIT): Use a closure instead of `(lambda...). - * erc-list.el: Use lexical-binding. - (erc-list-install-322-handler, erc-cmd-LIST): Adjust to change in - erc-once-with-server-event. - * erc-button.el: Use lexical-binding. - (erc-button-next-function): Use a closure instead of `(lambda...). - -2013-05-30 Glenn Morris - - * erc-backend.el: Require erc at run-time too. - -2013-05-21 Glenn Morris - - * erc-log.el (erc-network-name): Declare. - - * erc-notify.el (pcomplete--here): Declare. - (pcomplete/erc-mode/NOTIFY): Require pcomplete. - - * erc.el (erc-quit-reason-various-alist) - (erc-part-reason-various-alist): Don't mention zippy. - (erc-quit-reason, erc-part-reason): Remove zippy options. - (erc-quit-reason-zippy, erc-part-reason-zippy): Make obsolete. - If yow is not defined, fall back to -normal versions. - -2013-05-15 Glenn Morris - - * erc-list.el (erc-list): - * erc-menu.el (erc-menu): - * erc-ring.el (erc-ring): Define custom groups, for define-erc-module. - - * erc-list.el: Provide a feature. - -2013-05-09 Glenn Morris - - * erc-desktop-notifications.el (erc-notifications-icon): - Fix custom type. - -2013-02-13 Aidan Gauland - - * erc-match.el (erc-match-message): Fix last commit. - -2013-02-12 Aidan Gauland - - * erc-match.el (erc-match-message): - Don't truncate action messages. (Bug#13689) - -2013-02-09 Eli Zaretskii - - * erc-dcc.el (erc-dcc-get-file): Don't reference buffer-file-type. - -2013-01-11 Dmitry Antipov - - * erc-dcc.el (erc-dcc-send-file): Use point-min-marker. - (erc-dcc-chat-setup): Use point-max-marker. - -2013-01-04 Glenn Morris - - * erc-backend.el (312): Fix typo. (Bug#13235) - -2012-11-30 Glenn Morris - - * erc.el (erc-accidental-paste-threshold-seconds): Add :version. - -2012-11-30 Eric Hanchrow - - * erc.el (erc-last-input-time): New variable. - (erc-accidental-paste-threshold-seconds): New option to avoid - sending accidentally-pasted text to the server (Bug#11592). - (erc-send-current-line): Use it. - -2012-11-30 Chong Yidong - - * erc.el (erc-lurker-cleanup, erc-lurker-p): Use float-time. - -2012-11-23 Stefan Monnier - - * erc-backend.el: Fix last change that missed calls to `second' - (bug#12970). - -2012-11-19 Stefan Monnier - - Use cl-lib instead of cl, and interactive-p => called-interactively-p. - * erc-track.el, erc-networks.el, erc-netsplit.el, erc-dcc.el: - * erc-backend.el: Use cl-lib, nth, pcase, and called-interactively-p - instead of cl. - * erc-speedbar.el, erc-services.el, erc-pcomplete.el, erc-notify.el: - * erc-match.el, erc-log.el, erc-join.el, erc-ezbounce.el: - * erc-capab.el: Don't require cl since we don't use it. - * erc.el: Use cl-lib, nth, pcase, and called-interactively-p i.s.o cl. - (erc-lurker-ignore-chars, erc-common-server-suffixes): - Move before first use. - -2012-11-16 Glenn Morris - - * erc.el (erc-modules): Add "notifications". Tweak "hecomplete" doc. - -2012-10-28 Stefan Monnier - - * erc-backend.el: Only require `erc' during compilation (bug#12740). - -2012-10-18 Stefan Monnier - - * erc-backend.el: Require `erc' instead of autoloading its macros - (bug#12669). - -2012-10-15 Stefan Monnier - - * erc.el (erc-log): Make it into a defsubst. - (erc-with-server-buffer, define-erc-module, erc-with-buffer) - (erc-with-all-buffers-of-server): Use `declare'. - * erc-backend.el (erc-log): Adjust autoload accordingly. - -2012-10-07 Deniz Dogan - - * erc-log.el (erc-generate-log-file-name-function): - Clarify tags for various choices. (Bug#11186) - -2012-10-07 Glenn Morris - - * erc-button.el (erc-button-alist): Remove "finger". (Bug#4443) - -2012-10-07 Antoine Levitt - - * erc-stamp.el (erc-format-timestamp): Don't apply intangible - property to invisible stamps. (Bug#11706) - -2012-10-07 Glenn Morris - - * erc-backend.el (NICK): Handle pre-existing buffers. (Bug#12002) - -2012-10-06 Glenn Morris - - * erc.el (erc-lurker): - * erc-desktop-notifications.el (erc-notifications): - Add missing group :version tags. - -2012-10-04 Julien Danjou - - * erc-desktop-notifications.el: Rename from erc-notifications.el to - avoid clash with 8+3 filename format and erc-notify.el. - -2012-09-25 Chong Yidong - - * erc.el (erc-send-command): Use define-obsolete-function-alias. - -2012-09-17 Chong Yidong - - * erc-page.el (erc-page-function): - * erc-stamp.el (erc-stamp): Doc fix. - -2012-08-21 Josh Feinstein - - * erc-join.el (erc-autojoin-timing): Fix defcustom type. - -2012-08-21 Julien Danjou - - * erc-match.el (erc-match-message): - Use `erc-match-exclude-server-buffer' not - `erc-track-exclude-server-buffer'. - -2012-08-20 Josh Feinstein - - * erc.el (erc-display-message): Abstract message hiding decision - to new function erc-hide-current-message-p. - (erc-lurker): New customization group. - (erc-lurker-state, erc-lurker-trim-nicks, erc-lurker-ignore-chars) - (erc-lurker-hide-list, erc-lurker-cleanup-interval) - (erc-lurker-threshold-time): New variables. - (erc-lurker-maybe-trim, erc-lurker-initialize, erc-lurker-cleanup) - (erc-hide-current-message-p, erc-canonicalize-server-name) - (erc-lurker-update-status, erc-lurker-p): New functions. - Together they maintain state about which users have spoken in the last - erc-lurker-threshold-time, with all other users being considered - lurkers whose messages of types in erc-lurker-hide-list will not - be displayed by erc-display-message. - -2012-08-06 Julien Danjou - - * erc-match.el (erc-match-exclude-server-buffer) - (erc-match-message): Add new option to exclude server buffer from - matching. - -2012-07-21 Julien Danjou - - * erc-notifications.el: New file. - -2012-06-15 Julien Danjou - - * erc.el (erc-open): Use `auth-source' for password retrieval when - possible. - -2012-06-12 Chong Yidong - - * erc-dcc.el (erc-dcc-chat-filter-functions): Rename from - erc-dcc-chat-filter-hook, since this is an abnormal hook. - -2012-06-08 Chong Yidong - - * erc.el (erc-direct-msg-face, erc-header-line, erc-input-face) - (erc-command-indicator-face, erc-notice-face, erc-action-face) - (erc-error-face, erc-my-nick-face, erc-nick-default-face) - (erc-nick-msg-face): Use new-style face specs, and avoid :bold. - - * erc-button.el (erc-button): - * erc-goodies.el (erc-bold-face, erc-inverse-face) - (erc-underline-face, fg:erc-color-*): - * erc-match.el (erc-current-nick-face, erc-dangerous-host-face) - (erc-pal-face, erc-fool-face, erc-keyword-face): - * erc-stamp.el (erc-timestamp-face): Likewise. - -2012-06-02 Chong Yidong - - * erc-track.el (erc-track, erc-track-faces-priority-list) - (erc-track-faces-normal-list, erc-track-find-face) - (erc-track-modified-channels): Fix modeline -> mode line in docs. - -2012-05-14 Mike Kazantsev (tiny change) - - * erc-dcc.el (erc-dcc-handle-ctcp-send): Fix a regression - introduced on 2011-11-28 when fixing quoted filenames matching, - the regex group was not corrected. - -2012-05-13 Teemu Likonen - - * erc-backend.el (erc-server-timestamp-format): New variable to - allow specifying the timestamp format (bug#10779). - -2012-04-11 Vivek Dasmohapatra - - * erc-services.el (erc-nickserv-passwords): Don't display the - password (bug#4459). - -2012-04-10 Lars Magne Ingebrigtsen - - * erc-join.el (erc-server-join-channel): New function to look up - the channel password via auth-source. - (erc-autojoin-channels): Use it. - (erc-autojoin-after-ident): Ditto. - (erc-autojoin-channels-alist): Mention auth-source. - -2012-04-10 Deniz Dogan - - * erc.el (erc-display-prompt): Adds the field text property to the - ERC prompt. This allows users to use `kill-whole-line' to kill - all text back to the prompt given that it's on a single line - (bug#10841). - -2012-04-09 Chong Yidong - - * erc.el (erc-cmd-SET): Call custom-variable-p instead of - user-variable-p. - -2012-02-08 Glenn Morris - - * erc-backend.el (erc-coding-system-precedence): - * erc-join.el (erc-autojoin-delay, erc-autojoin-timing): - Add missing :version settings. - -2012-01-06 Glenn Morris - - * erc.el (erc-tls): Add autoload cookie. (Bug#10333) - -2011-12-31 Antoine Levitt - - * erc-goodies.el (erc-scroll-to-bottom): Use post-command-hook - rather than window-scroll-functions. Fixes a bug with word-wrap on - a tty. (Bug#9246) - -2011-11-28 Mike Kazantsev (tiny change) - - * erc-dcc.el (erc-dcc-ctcp-query-send-regexp): Update regexp to - match quoted filenames with spaces inside. - (erc-dcc-handle-ctcp-send): Update regexp match group numbers, - added processing of escaped quotes and backslashes if filename - itself was in quotes. - -2011-11-20 Juanma Barranquero - - * erc-log.el (erc-logging-enabled): Fix typo. - -2011-11-14 Juanma Barranquero - - * erc-notify.el (erc-notify-interval, erc-cmd-NOTIFY): Fix typos. - -2011-10-20 Chong Yidong - - * erc.el (define-erc-module): Fix autogenerated docstring to - reflect Emacs 24 minor mode changes. - - * erc-fill.el (erc-fill-mode): - * erc-track.el (erc-track-minor-mode): Doc fix. - -2011-09-23 Antoine Levitt - - * erc-button.el (erc-button-next-function): Scoping fix - (Bug#9487). - -2011-07-04 Vivek Dasmohapatra - - * erc.el (erc-generate-new-buffer-name): Reuse old buffer names - when reconnecting (bug#5563). - -2011-06-23 Lars Magne Ingebrigtsen - - * erc.el (erc-ssl): Made into a synonym for erc-tls, which - provides a superset of the same functionality. - (erc-open-ssl-stream): Remove. - (erc-open-tls-stream): Use `open-network-stream' instead of - `open-tls-stream' directly to be able to use the built-in TLS - support. - -2011-05-28 Stefan Monnier - - * erc-pcomplete.el (erc-pcompletions-at-point): Mark the completion - data as non-exclusive if it's using the default-completion-function. - (pcomplete-erc-parse-arguments): Rename pcomplete-parse-erc-arguments. - (pcomplete-erc-setup): Use new name. - -2011-05-03 Debarshi Ray (tiny change) - - * erc-backend.el (671): New response handler. - * erc.el (english): Add 671 to catalog. - -2011-04-29 Stefan Monnier - - * erc-pcomplete.el (erc-pcomplete-nick-postfix): Remove the " " in the - suffix that's added by pcomplete-termination-string anyway. - (pcomplete-erc-setup): Remove pcomplete-suffix-list setting now that - it's not needed any more. - -2011-04-26 Stefan Monnier - - * erc.el (erc-mode-map): Use completion-at-point. - (erc-mode): Tell completion-at-point to obey erc-complete-functions. - (erc-complete-word-at-point): New function. - (erc-complete-word): Make it obsolete. - * erc-pcomplete.el (erc-pcompletions-at-point): New function. - (pcomplete): Use it. - * erc-dcc.el (erc-dcc-chat-mode-map): Use completion-at-point. - (erc-dcc-chat-mode): Tell completion-at-point to obey - erc-complete-functions. - * erc-button.el (erc-button-next-function): New function extracted from - erc-button-next. - (button, erc-button-next): Use it. - -2011-04-20 Stefan Monnier - - * erc-hecomplete.el: Move to ../obsolete. - -2011-03-07 Chong Yidong - - * Version 23.3 released. - -2011-03-04 Julien Danjou - - * erc-track.el (erc-track-visibility): Fix :type. (Bug#6369) - -2011-02-10 Stefan Monnier - - * erc-list.el (erc-list-menu-mode-map): Move initialization - into declaration. - -2011-02-07 Julien Danjou - - * erc-track.el (erc-window-configuration-change): New function. - This will allow to track buffer visibility when a command is - finished to executed. Idea stolen from rcirc. - (track): Put erc-window-configuration-change in - window-configuration-change-hook. - (erc-modified-channels-update): Remove - erc-modified-channels-update from post-command-hook after update. - -2011-02-01 Sam Steingold - - * erc-list.el (erc-list-menu-mode): Inherit from `special-mode'. - -2011-01-31 Antoine Levitt (tiny change) - - * erc-track.el (track): Don't reset erc-modified-channels-object - each time erc-track-mode is activated. - -2011-01-13 Stefan Monnier - - * erc.el (erc-mode): - * erc-dcc.el (erc-dcc-chat-mode): Use define-derived-mode. - -2010-11-11 Glenn Morris - - * erc-lang.el (erc-cmd-LANG): Fix what may have been a typo. - -2010-11-05 Lars Magne Ingebrigtsen - - * erc-backend.el (erc-coding-system-precedence): New variable. - (erc-decode-string-from-target): Use it. - -2010-10-24 Julien Danjou - - * erc-backend.el (erc-server-JOIN): Set the correct target list on join. - - * erc-backend.el (erc-process-sentinel): Check that buffer is alive - before setting it as current buffer. - -2010-10-14 Juanma Barranquero - - * erc-xdcc.el (erc-xdcc-help-text): Fix typo in docstring. - -2010-10-10 Dan Nicolaescu - - * erc-list.el (erc-list-menu-mode-map): Declare and define in one step. - -2010-08-14 Vivek Dasmohapatra - - * erc-join.el (erc-autojoin-timing, erc-autojoin-delay): New vars. - (erc-autojoin-channels-delayed, erc-autojoin-after-ident): - New functions. - (erc-autojoin-channels): Allow autojoining after ident (Bug#5521). - -2010-08-08 Fran Litterio - - * erc-backend.el (erc-server-filter-function): - Call erc-log-irc-protocol. - - * erc.el (erc-toggle-debug-irc-protocol): - Bind erc-toggle-debug-irc-protocol to t. - -2010-05-07 Chong Yidong - - * Version 23.2 released. - -2010-03-10 Chong Yidong - - * Branch for 23.2. - -2010-02-07 Vivek Dasmohapatra - - * erc-services.el (erc-nickserv-alist): Fix defcustom type (Bug#5520). - -2010-01-25 Vivek Dasmohapatra - - * erc-backend.el (erc-session-connector): New var. - (erc-server-reconnect): Use it to reconnect via old - connector (Bug#4958). - - * erc.el (erc-determine-parameters): - Save erc-server-connect-function to erc-session-connector. - -2009-11-03 Stefan Monnier - - * erc.el (erc-display-line-1, erc-process-away): - * erc-truncate.el (erc-truncate-buffer-to-size): - Use with-current-buffer. - -2009-10-24 Glenn Morris - - * erc-dcc.el (pcomplete-erc-all-nicks): - * erc-notify.el (pcomplete-erc-all-nicks): - Autoload it, to silence compiler. - - * erc-dcc.el (pcomplete/erc-mode/DCC): Replace cl-function - remove-duplicates with erc-delete-dups. - -2009-09-27 Johan Bockgård - - * erc-button.el (erc-button-keymap): Bind `follow-link'. - -2009-09-26 Johan Bockgård - - * erc-button.el (erc-button-add-button): Only call - `widget-convert-button' in XEmacs. For Emacs (at least), it - doesn't seem to have any purpose except creating lots of overlays, - slowing everything down. - -2009-09-19 Glenn Morris - - * erc-lang.el (line): Define for compiler. - -2009-07-22 Kevin Ryde - - * erc.el (erc-cmd-MODE): Hyperlink urls in docstring with URL `...'. - -2009-03-13 D. Goel - - * erc-backend.el: In (multiple-value-bind/setq .. ls), - ls-> (values-list ls) throughout. - * erc.el: Ditto. - -2009-01-18 Michael Olson - - * erc.el (erc-header-line-uses-tabbar-p): Set to nil by default. - -2009-01-16 Glenn Morris - - * erc.el (erc-input-message): Conditionalize previous change for XEmacs. - - * erc-dcc.el (erc-dcc-server): Silence warning about obsolete function - behind fboundp test. - -2009-01-09 Glenn Morris - - * erc.el (erc-input-message): Replace last-command-char with - last-command-event. - -2009-01-08 Glenn Morris - - * erc.el (tabbar--local-hlf): Silence compiler. - -2009-01-03 Michael Olson - - * erc.el (erc-user-input): Do not include text properties when - returning user input. - -See ChangeLog.1 for earlier changes. - - Copyright (C) 2009-2025 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 3 of the License, 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. If not, see . - -;; Local Variables: -;; coding: utf-8 -;; add-log-time-zone-rule: t -;; End: diff --git a/lisp/erc/erc-autoaway.el b/lisp/erc/erc-autoaway.el deleted file mode 100644 index 5ef825677d1..00000000000 --- a/lisp/erc/erc-autoaway.el +++ /dev/null @@ -1,278 +0,0 @@ -;;; erc-autoaway.el --- Provides autoaway for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Jorgen Schaefer -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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-idle-method' is set to `emacs'.") - -(defvar erc-autoaway-last-sent-time (erc-current-time) - "The last time the user sent something.") - -(defvar erc-autoaway-caused-away nil - "Non-nil if this module was responsible for setting the user's away status.") - -(defvar erc-autoaway-idle-seconds) - -(defun erc-autoaway-reestablish-idletimer () - "Reestablish the Emacs idletimer. -If `erc-autoaway-idle-method' is `emacs', you must call this -function each time you change `erc-autoaway-idle-seconds'." - (interactive) - (when erc-autoaway-idletimer - (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))) - -(defun erc-autoaway-some-server-buffer () - "Return some ERC server buffer if its connection is alive. -If none is found, return nil." - (car (erc-buffer-list #'erc-open-server-buffer-p))) - -(defun erc-autoaway-insinuate-maybe (&optional server &rest _ignored) - "Add autoaway reset function to `post-command-hook' if at least one -ERC process is alive. - -This is used when `erc-autoaway-idle-method' is `user'." - (when (or server (erc-autoaway-some-server-buffer)) - (add-hook 'post-command-hook #'erc-autoaway-reset-idle-user))) - -(defun erc-autoaway-remove-maybe (&rest _ignored) - "Remove the autoaway reset function from `post-command-hook' if -no ERC process is alive. - -This is used when `erc-autoaway-idle-method' is `user'." - (unless (erc-autoaway-some-server-buffer) - (remove-hook 'post-command-hook #'erc-autoaway-reset-idle-user))) - -;;;###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: - -User idle time measures how long you have not been sending any -commands to Emacs. 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-idle-method' -for more information. - -IRC idle time measures how long since you last sent something (see -`erc-autoaway-last-sent-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: - ((when (boundp 'erc-autoaway-idle-method) - (add-hook 'erc-connect-pre-hook #'erc-autoaway-reset-indicators) - (setq erc-autoaway-last-sent-time (erc-current-time)) - (cond - ((eq erc-autoaway-idle-method 'irc) - (add-hook 'erc-send-completed-hook #'erc-autoaway-reset-idle-irc) - (add-hook 'erc-server-001-functions #'erc-autoaway-reset-idle-irc)) - ((eq erc-autoaway-idle-method 'user) - (add-hook 'erc-after-connect #'erc-autoaway-insinuate-maybe) - (add-hook 'erc-disconnected-hook #'erc-autoaway-remove-maybe) - (erc-autoaway-insinuate-maybe)) - ((eq erc-autoaway-idle-method 'emacs) - (erc-autoaway-reestablish-idletimer))) - (add-hook 'erc-timer-hook #'erc-autoaway-possibly-set-away) - (add-hook 'erc-server-305-functions #'erc-autoaway-reset-indicators))) - ;; Disable: - ((when (boundp 'erc-autoaway-idle-method) - (remove-hook 'erc-connect-pre-hook #'erc-autoaway-reset-indicators) - (cond - ((eq erc-autoaway-idle-method 'irc) - (remove-hook 'erc-send-completed-hook #'erc-autoaway-reset-idle-irc) - (remove-hook 'erc-server-001-functions #'erc-autoaway-reset-idle-irc)) - ((eq erc-autoaway-idle-method 'user) - (remove-hook 'post-command-hook #'erc-autoaway-reset-idle-user) - (remove-hook 'erc-after-connect #'erc-autoaway-insinuate-maybe) - (remove-hook 'erc-disconnected-hook #'erc-autoaway-remove-maybe)) - ((eq erc-autoaway-idle-method 'emacs) - (cancel-timer erc-autoaway-idletimer) - (setq erc-autoaway-idletimer nil))) - (remove-hook 'erc-timer-hook #'erc-autoaway-possibly-set-away) - (remove-hook 'erc-server-305-functions #'erc-autoaway-reset-indicators)))) - -(defcustom erc-autoaway-idle-method 'user - "The method used to determine how long you have been idle. -If `user', the time of the last command sent to Emacs is used. -If `emacs', the idle time in Emacs is used. -If `irc', the time of the last IRC command is used. - -The time itself is specified by `erc-autoaway-idle-seconds'. - -See `erc-autoaway-mode' for more information on the various -definitions of being idle." - :type '(choice (const :tag "User idle time" user) - (const :tag "Emacs idle time" emacs) - (const :tag "Last IRC action" irc)) - :set (lambda (sym val) - (if erc-autoaway-mode - (progn - (erc-autoaway-disable) - (set sym val) - (erc-autoaway-enable)) - (set sym val)))) - -(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." - :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'." - :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'." - :type 'regexp) - -(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." - :set (lambda (sym val) - (set-default sym val) - (when (eq erc-autoaway-idle-method 'emacs) - (erc-autoaway-reestablish-idletimer))) - :type 'number) - -(defcustom erc-autoaway-message - "I'm gone (autoaway after %i seconds of idletime)" - "Message ERC will use when setting you automatically away. -It is used as a `format' string with the argument of the idletime -in seconds." - :type 'string) - -(defun erc-autoaway-reset-idle-user (&rest _stuff) - "Reset the stored user idle time. -This is one global variable since a user talking on one net can -talk on another net too." - (when erc-auto-discard-away - (erc-autoaway-set-back #'erc-autoaway-remove-maybe)) - (setq erc-autoaway-last-sent-time (erc-current-time))) - -(defun erc-autoaway-reset-idle-irc (line &rest _stuff) - "Reset the stored IRC idle time. -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)) - (setq erc-autoaway-last-sent-time (erc-current-time))) - -(defun erc-autoaway-set-back (&optional none-alive-func) - "Discard the away state globally. - -NONE-ALIVE-FUNC is the function to call if no ERC processes are alive." - (let ((server-buffer (erc-autoaway-some-server-buffer))) - (if (and erc-autoaway-caused-away - (buffer-live-p server-buffer) - (with-current-buffer server-buffer erc-away)) - (erc-cmd-GAWAY "") - (when none-alive-func (funcall none-alive-func))))) - -(defun erc-autoaway-some-open-server-buffer () - "Return some ERC server buffer if its connection is alive and user is not away. -If none is found, return nil." - (car (erc-buffer-list (lambda () - (and (erc-open-server-buffer-p) - (not erc-away)))))) - -(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-server-connected - erc-auto-set-away - (not erc-autoaway-caused-away) - (erc-autoaway-some-open-server-buffer)) - (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 t))))) - -(defun erc-autoaway-set-away (idle-time &optional notest) - "Set the away state globally. - -If NOTEST is specified, do not check to see whether there is an -active server buffer available." - ;; 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 (or notest (erc-autoaway-some-open-server-buffer)) - (setq erc-autoaway-caused-away t) - (erc-cmd-GAWAY (format-message erc-autoaway-message idle-time)))) - -(defun erc-autoaway-reset-indicators (&rest _stuff) - "Reset indicators used by the erc-autoaway module." - (setq erc-autoaway-last-sent-time (erc-current-time)) - (setq erc-autoaway-caused-away nil)) - -(provide 'erc-autoaway) - -;;; erc-autoaway.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el deleted file mode 100644 index 8854ca522d9..00000000000 --- a/lisp/erc/erc-backend.el +++ /dev/null @@ -1,2924 +0,0 @@ -;;; erc-backend.el --- Backend network communication for ERC -*- lexical-binding:t -*- - -;; Copyright (C) 2004-2025 Free Software Foundation, Inc. - -;; Author: Lawrence Mitchell -;; Maintainer: Amin Bandali , F. Jason Park -;; Created: 2004-05-7 -;; Keywords: comm, 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file defines backend network communication handlers for ERC. -;; -;; How things work: -;; -;; You define a new handler with `define-erc-response-handler'. This -;; defines a function, a corresponding hook variable, and populates a -;; global hash table `erc-server-responses' with a map from response -;; to hook variable. See the function documentation for more -;; information. -;; -;; Upon receiving a line from the server, `erc-parse-server-response' -;; is called on it. -;; -;; A line generally looks like: -;; -;; LINE := ':' SENDER ' ' COMMAND ' ' (COMMAND-ARGS ' ')* ':' CONTENTS -;; SENDER := Not ':' | ' ' -;; COMMAND := Not ':' | ' ' -;; COMMAND-ARGS := Not ':' | ' ' -;; -;; This gets parsed and stuffed into an `erc-response' struct. You -;; can access the fields of the struct with: -;; -;; COMMAND --- `erc-response.command' -;; COMMAND-ARGS --- `erc-response.command-args' -;; CONTENTS --- `erc-response.contents' -;; SENDER --- `erc-response.sender' -;; LINE --- `erc-response.unparsed' -;; TAGS --- `erc-response.tags' -;; -;; WARNING, WARNING!! -;; It's probably not a good idea to destructively modify the list -;; of command-args in your handlers, since other functions down the -;; line may well need to access the arguments too. -;; -;; That is, unless you're /absolutely/ sure that your handler doesn't -;; invoke some other function that needs to use COMMAND-ARGS, don't do -;; something like -;; -;; (while (erc-response.command-args parsed) -;; (let ((a (pop (erc-response.command-args parsed)))) -;; ...)) -;; -;; The parsed response is handed over to -;; `erc-handle-parsed-server-response', which checks whether it should -;; carry out duplicate suppression, and then runs `erc-call-hooks'. -;; `erc-call-hooks' retrieves the relevant hook variable from -;; `erc-server-responses' and runs it. -;; -;; Most handlers then destructure the parsed response in some way -;; (depending on what the handler is, the arguments have different -;; meanings), and generally display something, usually using -;; `erc-display-message'. - -;;; TODO: - -;; o Generalize the display-line code so that we can use it to -;; display the stuff we send, as well as the stuff we receive. -;; Then, move all display-related code into another backend-like -;; file, erc-display.el, say. -;; -;; o Clean up the handlers using new display code (has to be written -;; first). - -;;; History: - -;; 2004/05/10 -- Handler bodies taken out of erc.el and ported to new -;; interface. - -;; 2005-08-13 -- Moved sending commands from erc.el. - -;;; Code: - -(eval-when-compile (require 'cl-lib)) -(require 'erc-common) - -(defvar erc--display-context) -(defvar erc--msg-prop-overrides) -(defvar erc--target) -(defvar erc-channel-list) -(defvar erc-channel-members) -(defvar erc-default-nicks) -(defvar erc-default-recipients) -(defvar erc-ensure-target-buffer-on-privmsg) -(defvar erc-hide-prompt) -(defvar erc-input-marker) -(defvar erc-insert-marker) -(defvar erc-join-buffer) -(defvar erc-networks--id) -(defvar erc-nick) -(defvar erc-nick-change-attempt-count) -(defvar erc-verbose-server-ping) - -(declare-function erc--ensure-query-member "erc" (name)) -(declare-function erc--ensure-query-members "erc" ()) -(declare-function erc--init-channel-modes "erc" (channel raw-args)) -(declare-function erc--open-target "erc" (target)) -(declare-function erc--parse-nuh "erc" (string)) -(declare-function erc--query-list "erc" ()) -(declare-function erc--remove-channel-users-but "erc" (nick)) -(declare-function erc--target-from-string "erc" (string)) -(declare-function erc--update-modes "erc" (raw-args)) -(declare-function erc-active-buffer "erc" nil) -(declare-function erc-add-default-channel "erc" (channel)) -(declare-function erc-banlist-update "erc" (proc parsed)) -(declare-function erc-buffer-filter "erc" (predicate &optional proc)) -(declare-function erc-buffer-list-with-nick "erc" (nick proc)) -(declare-function erc-channel-begin-receiving-names "erc" nil) -(declare-function erc-channel-end-receiving-names "erc" nil) -(declare-function erc-channel-p "erc" (channel)) -(declare-function erc-channel-receive-names "erc" (names-string)) -(declare-function erc-cmd-JOIN "erc" (channel &optional key)) -(declare-function erc-connection-established "erc" (proc parsed)) -(declare-function erc-current-nick "erc" nil) -(declare-function erc-current-nick-p "erc" (nick)) -(declare-function erc-current-time "erc" (&optional specified-time)) -(declare-function erc-default-target "erc" nil) -(declare-function erc-delete-default-channel "erc" (channel &optional buffer)) -(declare-function erc-display-error-notice "erc" (parsed string)) -(declare-function erc-display-server-message "erc" (_proc parsed)) -(declare-function erc-emacs-time-to-erc-time "erc" (&optional specified-time)) -(declare-function erc-format-message "erc" (msg &rest args)) -(declare-function erc-get-buffer "erc" (target &optional proc)) -(declare-function erc-handle-login "erc" nil) -(declare-function erc-handle-user-status-change "erc" (type nlh &optional l)) -(declare-function erc-ignored-reply-p "erc" (msg tgt proc)) -(declare-function erc-ignored-user-p "erc" (spec)) -(declare-function erc-is-message-ctcp-and-not-action-p "erc" (message)) -(declare-function erc-is-message-ctcp-p "erc" (message)) -(declare-function erc-log-irc-protocol "erc" (string &optional outbound)) -(declare-function erc-login "erc" nil) -(declare-function erc-network "erc-networks" nil) -(declare-function erc-networks--id-given "erc-networks" (arg &rest args)) -(declare-function erc-networks--id-reload "erc-networks" (arg &rest args)) -(declare-function erc-nickname-in-use "erc" (nick reason)) -(declare-function erc-parse-user "erc" (string)) -(declare-function erc-process-away "erc" (proc away-p)) -(declare-function erc-process-ctcp-query "erc" (proc parsed nick login host)) -(declare-function erc-remove-channel-member "erc" (channel nick)) -(declare-function erc-remove-channel-users "erc" nil) -(declare-function erc-remove-user "erc" (nick)) -(declare-function erc-sec-to-time "erc" (ns)) -(declare-function erc-server-buffer "erc" nil) -(declare-function erc-set-active-buffer "erc" (buffer)) -(declare-function erc-set-current-nick "erc" (nick)) -(declare-function erc-time-diff "erc" (t1 t2)) -(declare-function erc-trim-string "erc" (s)) -(declare-function erc-update-mode-line "erc" (&optional buffer)) -(declare-function erc-update-mode-line-buffer "erc" (buffer)) -(declare-function erc-wash-quit-reason "erc" (reason nick login host)) - -(declare-function erc--determine-speaker-message-format-args "erc" - (nick target message queryp privmsgp statusmsgp inputp - &optional prefix disp-nick)) -(declare-function erc-display-message "erc" - (parsed type buffer msg &rest args)) -(declare-function erc-get-buffer-create "erc" - (server port target &optional tgt-info id)) -(declare-function erc-process-ctcp-reply "erc" - (proc parsed nick login host msg)) -(declare-function erc-update-channel-topic "erc" - (channel topic &optional modify)) -(declare-function erc-update-user-nick "erc" - (nick &optional new-nick host login full-name info)) -(declare-function erc-open "erc" - (&optional server port nick full-name connect passwd tgt-list - channel process client-certificate user id)) -(declare-function erc-update-channel-member "erc" - (channel nick new-nick - &optional add voice halfop op admin owner host - login full-name info update-message-time)) - -;;;; Variables and options - -(defvar-local erc-session-password nil - "The password used for the current session. -This should be a string or a function returning a string.") - -(defvar erc-server-responses (make-hash-table :test #'equal) - "Hash table mapping server responses to their handler hooks.") - -;;; User data - -(defvar-local erc-server-current-nick nil - "Nickname on the current server. -Use `erc-current-nick' to access this.") - -(defvar-local erc-session-user-full-name nil - "Real name used for the current session. -Sent as the last argument to the USER command.") - -(defvar-local erc-session-username nil - "Username used for the current session. -Sent as the first argument of the USER command.") - -;;; Server attributes - -(defvar-local erc-server-process nil - "The process object of the corresponding server connection.") - -(defvar-local erc-session-server nil - "The server name used to connect to for this session.") - -(defvar-local erc-session-connector nil - "The function used to connect to this session (nil for the default).") - -(defvar-local erc-session-port nil - "The port used to connect to.") - -(defvar-local erc-session-client-certificate nil - "TLS client certificate used when connecting over TLS. -If non-nil, should either be a list where the first element is -the certificate key file name, and the second element is the -certificate file name itself, or t, which means that -`auth-source' will be queried for the key and the certificate.") - -(defvar-local erc-server-announced-name nil - "The name the server announced to use.") - -(defvar-local erc-server-version nil - "The name and version of the server's ircd.") - -(defvar-local erc-server-parameters nil - "Alist listing the supported server parameters. - -This is only set if the server sends 005 messages saying what is -supported on the server. - -Entries are of the form: - (PARAMETER . VALUE) -or - (PARAMETER) if no value is provided. - -where PARAMETER is a string and VALUE is a string or nil. For -compatibility, a raw parameter of the form \"FOO=\" becomes -(\"FOO\" . \"\") even though it's equivalent to the preferred -canonical form \"FOO\" and its Lisp representation (\"FOO\"). - -Some examples of possible parameters sent by servers: -CHANMODES=b,k,l,imnpst - list of supported channel modes -CHANNELLEN=50 - maximum length of channel names -CHANTYPES=#&!+ - supported channel prefixes -CHARMAPPING=rfc1459 - character mapping used for nickname and channels -KICKLEN=160 - maximum allowed kick message length -MAXBANS=30 - maximum number of bans per channel -MAXCHANNELS=10 - maximum number of channels allowed to join -NETWORK=EFnet - the network identifier -NICKLEN=9 - maximum allowed length of nicknames -PREFIX=(ov)@+ - list of channel modes and the user prefixes if user has mode -RFC2812 - server supports RFC 2812 features -SILENCE=10 - supports the SILENCE command, maximum allowed number of entries -TOPICLEN=160 - maximum allowed topic length -WALLCHOPS - supports sending messages to all operators in a channel") - -(defvar-local erc--isupport-params nil - "Hash map of \"ISUPPORT\" params. -Keys are symbols. Values are lists of zero or more strings with hex -escapes removed. ERC normalizes incoming parameters of the form -\"FOO=\" to (FOO).") - -;;; Server and connection state - -(defvar erc-server-ping-timer-alist nil - "Mapping of server buffers to their specific ping timer.") - -(defvar-local erc-server-connected nil - "Non-nil if the current buffer belongs to an active IRC connection. -To determine whether an underlying transport is connected, use the -function `erc-server-process-alive' instead.") - -(defvar-local erc-server-reconnect-count 0 - "Number of times we have failed to reconnect to the current server.") - -(defvar-local erc--server-reconnect-display-timer nil - "Timer that resets `erc--server-last-reconnect-count' to zero. -Becomes non-nil in all server buffers when an IRC connection is -first \"established\" and carries out its duties -`erc-auto-reconnect-display-timeout' seconds later.") - -(defvar-local erc--server-last-reconnect-count 0 - "Snapshot of reconnect count when the connection was established.") - -(defvar-local erc--server-reconnect-timer nil - "Auto-reconnect timer for a network context.") - -(defvar-local erc-server-quitting nil - "Non-nil if the user requests a quit.") - -(defvar-local erc-server-reconnecting nil - "Non-nil if the user requests an explicit reconnect, and the -current IRC process is still alive.") -(make-obsolete-variable 'erc-server-reconnecting - "see `erc--server-reconnecting'" "29.1") - -(defvar erc--server-reconnecting nil - "An alist of buffer-local vars and their values when reconnecting. -This is for the benefit of local modules and `erc-mode-hook' -members so they can access buffer-local data from the previous -session when reconnecting. Once `erc-reuse-buffers' is retired -and fully removed, modules can switch to leveraging the -`permanent-local' property instead.") - -(defvar erc--server-post-connect-hook '(erc-networks--warn-on-connect) - "Functions to run when a network connection is successfully opened. -Though internal, this complements `erc-connect-pre-hook' in that -it bookends the process rather than the logical connection, which -is the domain of `erc-before-connect' and `erc-after-connect'. -Note that unlike `erc-connect-pre-hook', this only runs in server -buffers, and it does so immediately before the first protocol -exchange.") - -(defvar-local erc-server-timed-out nil - "Non-nil if the IRC server failed to respond to a ping.") - -(defvar-local erc-server-banned nil - "Non-nil if the user is denied access because of a server ban.") - -(defvar-local erc-server-error-occurred nil - "Non-nil if the user triggers some server error.") - -(defvar-local erc-server-lines-sent nil - "Line counter.") - -(defvar-local erc-server-last-peers nil - "Last peers used, both sender and receiver. -Those are used for /MSG destination shortcuts.") - -(defvar-local erc-server-last-sent-time nil - "Time the message was sent. -This is useful for flood protection.") - -(defvar-local erc-server-last-ping-time nil - "Time the last ping was sent. -This is useful for flood protection.") - -(defvar-local erc-server-last-received-time nil - "Time the last message was received from the server. -This is useful for detecting hung connections.") - -(defvar-local erc-server-lag nil - "Calculated server lag time in seconds. -This variable is only set in a server buffer.") - -(defvar-local erc-server-filter-data nil - "The data that arrived from the server but has not been processed yet.") - -(defvar-local erc-server-duplicates (make-hash-table :test 'equal) - "Internal variable used to track duplicate messages.") - -;; From Circe -(defvar-local erc-server-processing-p nil - "Non-nil when we're currently processing a message. - -When ERC receives a private message, it sets up a new buffer for -this query. These in turn, though, do start flyspell. This -involves starting an external process, in which case Emacs will -wait - and when it waits, it does accept other stuff from, say, -network exceptions. So, if someone sends you two messages -quickly after each other, ispell is started for the first, but -might take long enough for the second message to be processed -first.") - -(defvar-local erc-server-flood-last-message 0 - "When we sent the last message. -See `erc-server-flood-margin' for an explanation of the flood -protection algorithm.") - -(defvar-local erc-server-flood-queue nil - "The queue of messages waiting to be sent to the server. -See `erc-server-flood-margin' for an explanation of the flood -protection algorithm.") - -(defvar-local erc-server-flood-timer nil - "The timer to resume sending.") - -;;; IRC protocol and misc options - -(defgroup erc-server nil - "Parameters for dealing with IRC servers." - :group 'erc) - -(defcustom erc-server-auto-reconnect t - "Non-nil means that ERC will attempt to reestablish broken connections. - -Reconnection will happen automatically for any unexpected disconnection." - :type 'boolean) - -(defcustom erc-server-reconnect-attempts 2 - "Number of times that ERC will attempt to reestablish a broken connection. -If t, always attempt to reconnect. - -This only has an effect if `erc-server-auto-reconnect' is non-nil." - :type '(choice (const :tag "Always reconnect" t) - integer)) - -(defcustom erc-server-reconnect-timeout 1 - "Number of seconds to wait between successive reconnect attempts. -If this value is too low, servers may reject your initial nick -request upon reconnecting because they haven't yet noticed that -your previous connection is dead. If this happens, try setting -this value to 120 or greater and/or exploring the option -`erc-services-regain-alist', which may provide a more proactive -means of handling this situation on some servers." - :type 'number) - -(defcustom erc-server-reconnect-function 'erc-server-prefer-check-reconnect - "Function called by the reconnect timer to create a new connection. -Called with a server buffer as its only argument. Potential uses -include exponential backoff and probing for connectivity prior to -dialing. Use `erc-schedule-reconnect' to instead try again later -and optionally alter the attempts tally." - :package-version '(ERC . "5.6.1") - :type '(choice (function-item erc-server-delayed-reconnect) - (function-item erc-server-delayed-check-reconnect) - (function-item erc-server-prefer-check-reconnect) - function)) - -(defcustom erc-split-line-length 440 - "The maximum length of a single message. -ERC normally splits chat input submitted at its prompt into -multiple messages when the initial size exceeds this value in -bytes. Modules can tell ERC to forgo splitting entirely by -setting this to zero locally or, preferably, by binding it around -a remapped `erc-send-current-line' command. - -IRC allows for lines up to 512 bytes. Two of them are CR LF. -And a typical message looks like this: - - :nicky!uhuser@host212223.dialin.fnordisp.net PRIVMSG #lazybastards :Hello! - -You can limit here the maximum length of the \"Hello!\" part. -Good luck." - :type 'integer) - -(defcustom erc-coding-system-precedence '(utf-8 undecided) - "List of coding systems to be preferred when receiving a string from the server. -This will only be consulted if the coding system in -`erc-server-coding-system' is `undecided'." - :version "24.1" - :type '(repeat coding-system)) - -(defcustom erc-server-coding-system (if (and (coding-system-p 'undecided) - (coding-system-p 'utf-8)) - '(utf-8 . undecided) - nil) - "The default coding system for incoming and outgoing text. -This is either a coding system, a cons, a function, or nil. - -If a cons, the encoding system for outgoing text is in the car -and the decoding system for incoming text is in the cdr. The most -interesting use for this is to put `undecided' in the cdr. This -means that `erc-coding-system-precedence' will be consulted, and the -first match there will be used. - -If a function, it is called with the argument `target' and should -return a coding system or a cons as described above. - -If you need to send non-ASCII text to people not using a client that -does decoding on its own, you must tell ERC what encoding to use. -Emacs cannot guess it, since it does not know what the people on the -other end of the line are using." - :type '(choice (const :tag "None" nil) - coding-system - (cons (coding-system :tag "encoding" :value utf-8) - (coding-system :tag "decoding" :value undecided)) - function)) - -(defcustom erc-encoding-coding-alist nil - "Alist of target regexp and coding-system pairs to use. -This overrides `erc-server-coding-system' depending on the -current target as returned by `erc-default-target'. - -Example: If you know that the channel #linux-ru uses the coding-system -`cyrillic-koi8', then add (\"#linux-ru\" . cyrillic-koi8) to the -alist." - :type '(repeat (cons (regexp :tag "Target") - coding-system))) - -(defcustom erc-server-connect-function #'erc-open-network-stream - "Function used to initiate a connection. -It should take same arguments as `open-network-stream' does." - :type 'function) - -(defcustom erc-server-prevent-duplicates '("301") - "Either nil or a list of strings. -Each string is a IRC message type, like PRIVMSG or NOTICE. -All Message types in that list of subjected to duplicate prevention." - :type '(repeat string)) - -(defcustom erc-server-duplicate-timeout 60 - "The time allowed in seconds between duplicate messages. - -If two identical messages arrive within this value of one another, the second -isn't displayed." - :type 'integer) - -(defcustom erc-server-timestamp-format "%Y-%m-%d %T" - "Timestamp format used with server response messages. -This string is processed using `format-time-string'." - :version "24.3" - :type 'string) - -;;; Flood-related - -;; Most of this is courtesy of Jorgen Schaefer and Circe -;; (https://www.nongnu.org/circe) - -(defcustom erc-server-flood-margin 10 - "A margin on how much excess data we send. -The flood protection algorithm of ERC works like the one -detailed in RFC 2813, section 5.8 \"Flood control of clients\". - - * If `erc-server-flood-last-message' is less than the current - time, set it equal. - * While `erc-server-flood-last-message' is less than - `erc-server-flood-margin' seconds ahead of the current - time, send a message, and increase - `erc-server-flood-last-message' by - `erc-server-flood-penalty' for each message." - :type 'integer) - -(defcustom erc-server-flood-penalty 3 - "How much we penalize a message. -See `erc-server-flood-margin' for an explanation of the flood -protection algorithm." - :type 'integer) - -;; Ping handling - -(defcustom erc-server-send-ping-interval 30 - "Interval of sending pings to the server, in seconds. -If this is set to nil, pinging the server is disabled." - :type '(choice (const :tag "Disabled" nil) - (integer :tag "Seconds"))) - -(defcustom erc-server-send-ping-timeout 120 - "If the time between ping and response is greater than this, reconnect. -The time is in seconds. - -This must be greater than or equal to the value for -`erc-server-send-ping-interval'. - -If this is set to nil, never try to reconnect." - :type '(choice (const :tag "Disabled" nil) - (integer :tag "Seconds"))) - -(defvar-local erc-server-ping-handler nil - "The periodic server ping timer.") - -;;;; Helper functions - -(defvar erc--reject-unbreakable-lines nil - "Signal an error when a line exceeds `erc-split-line-length'. -Sending such lines and hoping for the best is no longer supported -in ERC 5.6. This internal var exists as a possibly temporary -escape hatch for inhibiting their transmission.") - -(defun erc--split-line (longline) - (let* ((coding (erc-coding-system-for-target nil)) - (original-window-buf (window-buffer (selected-window))) - out) - (when (consp coding) - (setq coding (car coding))) - (setq coding (coding-system-change-eol-conversion coding 'unix)) - (with-temp-buffer - (unwind-protect - (progn - (set-window-buffer (selected-window) (current-buffer)) - (insert longline) - (goto-char (point-min)) - (while (not (eobp)) - (let ((upper (filepos-to-bufferpos erc-split-line-length - 'exact coding))) - (goto-char (or upper (point-max))) - (unless (eobp) - (skip-chars-backward "^ \t")) - (when (bobp) - (when erc--reject-unbreakable-lines - (user-error - (substitute-command-keys - (concat "Unbreakable line encountered (Recover input" - " with \\[erc-previous-command])")))) - (goto-char upper)) - (when-let* ((cmp (find-composition (point) (1+ (point))))) - (if (= (car cmp) (point-min)) - (goto-char (nth 1 cmp)) - (goto-char (car cmp))))) - (when (= (point-min) (point)) - (goto-char (point-max))) - (push (buffer-substring-no-properties (point-min) (point)) out) - (delete-region (point-min) (point))) - (or (nreverse out) (list ""))) - (set-window-buffer (selected-window) original-window-buf))))) - -;; From Circe -(defun erc-split-line (longline) - "Return a list of lines which are not too long for IRC. -The length is specified in `erc-split-line-length'. - -Currently this is called by `erc-send-input'." - (let* ((coding (erc-coding-system-for-target nil)) - (charset (if (consp coding) (car coding) coding))) - (with-temp-buffer - (insert longline) - ;; The line lengths are in octets, not characters (because these - ;; are server protocol limits), so we have to first make the - ;; text into bytes, then fold the bytes on "word" boundaries, - ;; and then make the bytes into text again. - (encode-coding-region (point-min) (point-max) charset) - (let ((fill-column erc-split-line-length)) - (fill-region (point-min) (point-max) - nil t)) - (decode-coding-region (point-min) (point-max) charset) - (split-string (buffer-string) "\n")))) - -(defun erc-forward-word () - "Move forward one word, ignoring any subword settings. -If no `subword-mode' is active, then this is (forward-word)." - (skip-syntax-forward "^w") - (> (skip-syntax-forward "w") 0)) - -(defun erc-word-at-arg-p (pos) - "Report whether the char after a given POS has word syntax. -If POS is out of range, the value is nil." - (let ((c (char-after pos))) - (if c - (eq ?w (char-syntax c)) - nil))) - -(defun erc-bounds-of-word-at-point () - "Return the bounds of word at point, or nil if we're not at a word. -If no `subword-mode' is active, then this is -\(bounds-of-thing-at-point \\='word)." - (if (or (erc-word-at-arg-p (point)) - (erc-word-at-arg-p (1- (point)))) - (save-excursion - (let* ((start (progn (skip-syntax-backward "w") (point))) - (end (progn (skip-syntax-forward "w") (point)))) - (cons start end))) - nil)) - -;; Used by CTCP functions -(defun erc-upcase-first-word (str) - "Upcase the first word in STR." - (with-temp-buffer - (insert str) - (goto-char (point-min)) - (upcase-region (point) (progn (erc-forward-word) (point))) - (buffer-string))) - -(defun erc-server-setup-periodical-ping (buffer) - "Set up a timer to periodically ping the current server. -The current buffer is given by BUFFER." - (with-current-buffer buffer - (when erc-server-ping-handler - (cancel-timer erc-server-ping-handler)) - (when erc-server-send-ping-interval - (setq erc-server-ping-handler (run-with-timer - 4 erc-server-send-ping-interval - #'erc-server-send-ping - buffer)) - - ;; I check the timer alist for an existing timer. If one exists, - ;; I get rid of it - (let ((timer-tuple (assq buffer erc-server-ping-timer-alist))) - (if timer-tuple - ;; this buffer already has a timer. Cancel it and set the new one - (progn - (cancel-timer (cdr timer-tuple)) - (setf (cdr (assq buffer erc-server-ping-timer-alist)) erc-server-ping-handler)) - - ;; no existing timer for this buffer. Add new one - (add-to-list 'erc-server-ping-timer-alist - (cons buffer erc-server-ping-handler))))))) - -(defun erc-server-process-alive (&optional buffer) - "Return non-nil when BUFFER has an `erc-server-process' open or running." - (with-current-buffer (or buffer (current-buffer)) - (and erc-server-process - (processp erc-server-process) - (memq (process-status erc-server-process) '(run open))))) - -;;;; Connecting to a server -(defun erc-open-network-stream (name buffer host service &rest parameters) - "Like `open-network-stream', but does non-blocking IO." - (let ((p (plist-put parameters :nowait t))) - (apply #'open-network-stream name buffer host service p))) - -(cl-defmethod erc--register-connection () - "Perform opening IRC protocol exchange with server." - (run-hooks 'erc--server-post-connect-hook) - (erc-login)) - -(defvar erc--server-post-dial-function - #'erc--server-propagate-failed-connection - "Function called one second after creating a server process. -Called with the newly created process just before the opening IRC -protocol exchange.") - -(defun erc--server-propagate-failed-connection (process) - "Ensure the PROCESS sentinel runs at least once on early failure. -Act as a watchdog timer to force `erc-process-sentinel' and its -finalizers, like `erc-disconnected-hook', to run when PROCESS has -a status of `failed' after one second. But only do so when its -error data is something ERC recognizes. Print an explanation to -the server buffer in any case." - (when (eq (process-status process) 'failed) - (erc-display-message - nil '(notice error) (process-buffer process) - (format "Process exit status: %S" (process-exit-status process))) - (pcase (process-exit-status process) - (111 - (erc-process-sentinel process "failed with code 111\n")) - (`(file-error . ,_) - (erc-process-sentinel process "failed with code -523\n")) - ((rx "tls" (+ nonl) "failed") - (erc-process-sentinel process "failed with code -525\n"))))) - -(defvar erc--server-connect-dumb-ipv6-regexp - ;; Not for validation (gives false positives). - (rx bot "[" (group (+ (any xdigit digit ":.")) (? "%" (+ alnum))) "]" eot)) - -(defun erc-server-connect (server port buffer &optional client-certificate) - "Perform the connection and login using the specified SERVER and PORT. -We will store server variables in the buffer given by BUFFER. -CLIENT-CERTIFICATE may optionally be used to specify a TLS client -certificate to use for authentication when connecting over -TLS (see `erc-session-client-certificate' for more details)." - (when (string-match erc--server-connect-dumb-ipv6-regexp server) - (setq server (match-string 1 server))) - (let ((msg (erc-format-message 'connect ?S server ?p port)) process - (args `(,(format "erc-%s-%s" server port) nil ,server ,port))) - (when client-certificate - (setq args `(,@args :client-certificate ,client-certificate))) - (message "%s" msg) - (setq process (apply erc-server-connect-function args)) - (unless (processp process) - (error "Connection attempt failed")) - ;; Misc server variables - (with-current-buffer buffer - (setq erc-server-filter-data nil) - (setq erc-server-process process) - (setq erc-server-quitting nil) - (setq erc-server-reconnecting nil - erc--server-reconnect-timer nil) - (setq erc-server-timed-out nil) - (setq erc-server-banned nil) - (setq erc-server-error-occurred nil) - (let ((time (erc-current-time))) - (setq erc-server-last-sent-time time) - (setq erc-server-last-ping-time time) - (setq erc-server-last-received-time time)) - (setq erc-server-lines-sent 0) - ;; last peers (sender and receiver) - (setq erc-server-last-peers (cons nil nil))) - ;; we do our own encoding and decoding - (when (fboundp 'set-process-coding-system) - (set-process-coding-system process 'raw-text)) - ;; process handlers - (set-process-sentinel process #'erc-process-sentinel) - (set-process-filter process #'erc-server-filter-function) - (set-process-buffer process buffer) - (erc-log "\n\n\n********************************************\n") - (message "%s" (erc-format-message - 'login ?n - (with-current-buffer buffer (erc-current-nick)))) - ;; wait with script loading until we receive a confirmation (first - ;; MOTD line) - (if (eq (process-status process) 'connect) - ;; waiting for a non-blocking connect - keep the user informed - (let ((erc--msg-prop-overrides `((erc--skip . (stamp)) - ,@erc--msg-prop-overrides))) - (erc-display-message nil nil buffer "Opening connection..\n") - (run-at-time 1 nil erc--server-post-dial-function process)) - (message "%s...done" msg) - (erc--register-connection)))) - -(defun erc-server-reconnect () - "Reestablish the current IRC connection. -Make sure you are in an ERC buffer when running this." - (let ((buffer (erc-server-buffer))) - (unless (buffer-live-p buffer) - (if (eq major-mode 'erc-mode) - (setq buffer (current-buffer)) - (error "Reconnect must be run from an ERC buffer"))) - (with-current-buffer buffer - (erc-update-mode-line) - (erc-set-active-buffer (current-buffer)) - (setq erc-server-last-sent-time 0) - (setq erc-server-lines-sent 0) - (let ((erc-server-connect-function (or erc-session-connector - #'erc-open-network-stream)) - (erc--server-reconnecting (buffer-local-variables))) - (erc-open erc-session-server erc-session-port erc-server-current-nick - erc-session-user-full-name t erc-session-password - nil nil nil erc-session-client-certificate - erc-session-username - (erc-networks--id-given erc-networks--id)) - (defvar erc-reuse-buffers) - (unless (with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers) - (cl-assert (not (eq buffer (current-buffer))))))))) - -(defun erc-server-delayed-reconnect (buffer) - (if (buffer-live-p buffer) - (with-current-buffer buffer - (erc-server-reconnect)))) - -(defun erc--server-reconnect-opened (buffer process) - "Reconnect session for server BUFFER using open PROCESS." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (let* ((orig erc-session-connector) - (erc-session-connector - (lambda (&rest _) - (setq erc-session-connector orig) - process))) - (erc-server-reconnect))))) - -(defvar-local erc--server-reconnect-timeout nil) - -;; These variables exist for use in unit tests. -(defvar erc--server-reconnect-timeout-check 10) -(defvar erc--server-reconnect-timeout-scale-function - #'erc--server-reconnect-timeout-double) - -(defun erc--server-reconnect-timeout-double (existing) - "Double EXISTING timeout, but cap it at 5 minutes." - (min 300 (* existing 2))) - -(defun erc--recon-probe-reschedule (proc) - "Print a message saying PROC's intended peer can't be reached. -Then call `erc-schedule-reconnect'." - (let ((buffer (or (and-let* ((proc) - (buffer (process-buffer proc)) - ((buffer-live-p buffer)) - (buffer))) - (current-buffer)))) - (with-current-buffer buffer - (let ((erc-server-reconnect-timeout - (or erc--server-reconnect-timeout - erc-server-reconnect-timeout))) - (when (and proc (not (eq proc erc-server-process))) - (set-process-sentinel proc #'ignore) - (delete-process proc)) - (erc-display-message nil '(notice error) buffer - 'recon-probe-nobody-home) - (erc-schedule-reconnect buffer 0))))) - -(defvar erc-server-delayed-check-reconnect-reuse-process-p t - "Whether to reuse a successful probe as the session process.") - -(defun erc--recon-probe-sentinel (proc event) - "Send a \"PING\" to PROC's peer on an \"open\" EVENT. -Otherwise, try connecting from scratch again after timeout." - (pcase event - ("open\n" - (set-process-sentinel proc #'ignore) - ;; This has been observed to possibly raise a `file-error'. - (if erc-server-delayed-check-reconnect-reuse-process-p - (run-at-time nil nil #'erc--server-reconnect-opened - (process-buffer proc) proc) - (run-at-time nil nil #'delete-process proc) - (run-at-time nil nil #'erc-server-delayed-reconnect - (process-buffer proc)))) - ((or "connection broken by remote peer\n" (rx bot "failed")) - (run-at-time nil nil #'erc--recon-probe-reschedule proc)))) - -(defun erc--recon-probe-check (proc expire) - "Restart reconnect probe if PROC has failed or EXPIRE time has passed. -Otherwise, if PROC's buffer is live and its status is `connect', arrange -for running again in 1 second." - (let* ((buffer (process-buffer proc)) - ;; - status) - (cond ((not (buffer-live-p buffer))) - ((time-less-p expire (current-time)) - ;; TODO convert into proper catalog message for i18n. - (erc-display-message nil 'error buffer "Timed out while dialing...") - (erc--recon-probe-reschedule proc)) - ((eq (setq status (process-status proc)) 'failed) - (erc--recon-probe-reschedule proc)) - ((eq status 'connect) - (run-at-time 1 nil #'erc--recon-probe-check proc expire))))) - -;; This probing strategy may appear to hang at various junctures. It's -;; assumed that when *Messages* contains "Waiting for socket ..." or -;; similar, progress will be made eventually. -(defun erc-server-delayed-check-reconnect (buffer) - "Wait for internet connectivity before trying to reconnect. -Use server BUFFER's cached session info to reestablish the logical -connection at the IRC protocol level. Do this by probing for any -response to a PING, including a hang up, before (possibly) dialing again -and commencing with \"connection registration\". Make no distinction -between configuration issues and the absence of service in printed -feedback. For example, expect users of proxy-based connectors, like -`erc-open-socks-tls-stream', to ensure their setup works before choosing -this function as their reconnector." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (setq erc--server-reconnect-timeout - (funcall erc--server-reconnect-timeout-scale-function - (or erc--server-reconnect-timeout - erc-server-reconnect-timeout))) - (condition-case _ - (let* ((cert erc-session-client-certificate) - (server (if (string-match erc--server-connect-dumb-ipv6-regexp - erc-session-server) - (match-string 1 erc-session-server) - erc-session-server)) - (name (if erc-server-delayed-check-reconnect-reuse-process-p - (format "erc-%s-%s" server erc-session-port) - "*erc-connectivity-check*")) - (proc (apply erc-session-connector name - nil server erc-session-port - (and cert (list :client-certificate cert)))) - (status (process-status proc))) - (set-process-buffer proc buffer) - (set-process-filter proc #'ignore) - (if (not (eq status 'connect)) ; :nowait is nil - (erc--recon-probe-sentinel proc (if (eq status 'open) - "open\n" - "failed")) - (run-at-time 1 nil #'erc--recon-probe-check proc - (time-add erc--server-reconnect-timeout-check - (current-time))) - (set-process-sentinel proc #'erc--recon-probe-sentinel))) - ;; E.g., "make client process failed" "Connection refused". - (file-error (erc--recon-probe-reschedule nil)) - ;; C-g during blocking connect, like with the SOCKS connector. - (quit (erc--cancel-auto-reconnect-timer)))))) - -(defun erc-server-prefer-check-reconnect (buffer) - "Defer to another reconnector based on BUFFER's `erc-session-connector'. -Prefer `erc-server-delayed-check-reconnect' if the connector is known to -be \"check-aware\". Otherwise, use `erc-server-delayed-reconnect'." - (if (memq (buffer-local-value 'erc-session-connector buffer) - '(erc-open-tls-stream - erc-open-network-stream - erc-open-socks-tls-stream)) - (erc-server-delayed-check-reconnect buffer) - (erc-server-delayed-reconnect buffer))) - -(defun erc-server-filter-function (process string) - "The process filter for the ERC server." - (with-current-buffer (process-buffer process) - (setq erc-server-last-received-time (erc-current-time)) - ;; If you think this is written in a weird way - please refer to the - ;; docstring of `erc-server-processing-p' - (if erc-server-processing-p - (setq erc-server-filter-data - (if erc-server-filter-data - (concat erc-server-filter-data string) - string)) - ;; This will be true even if another process is spawned! - (let ((erc-server-processing-p t)) - (setq erc-server-filter-data (if erc-server-filter-data - (concat erc-server-filter-data - string) - string)) - (while (and erc-server-filter-data - (string-match "[\n\r]+" erc-server-filter-data)) - (let ((line (substring erc-server-filter-data - 0 (match-beginning 0)))) - (setq erc-server-filter-data - (if (= (match-end 0) - (length erc-server-filter-data)) - nil - (substring erc-server-filter-data - (match-end 0)))) - (erc-log-irc-protocol line nil) - (erc-parse-server-response process line))))))) - -(defun erc--server-reconnect-p (event) - "Return non-nil when ERC should attempt to reconnect. -EVENT is the message received from the closed connection process." - (and erc-server-auto-reconnect - (not erc-server-banned) - ;; make sure we don't infinitely try to reconnect, unless the - ;; user wants that - (or (eq erc-server-reconnect-attempts t) - (and (integerp erc-server-reconnect-attempts) - (< erc-server-reconnect-count - erc-server-reconnect-attempts))) - (or erc-server-timed-out - (not (string-match "^deleted" event))) - ;; open-network-stream-nowait error for connection refused - (if (string-match "^failed with code 111" event) 'nonblocking t))) - -(defun erc-server-reconnect-p (event) - "Return non-nil if ERC should attempt to reconnect automatically. -EVENT is the message received from the closed connection process." - (declare (obsolete "see `erc--server-reconnect-p'" "29.1")) - (or (with-suppressed-warnings ((obsolete erc-server-reconnecting)) - erc-server-reconnecting) - (erc--server-reconnect-p event))) - -(defun erc--server-last-reconnect-on-disconnect (&rest _) - (remove-hook 'erc-disconnected-hook - #'erc--server-last-reconnect-on-disconnect t) - (erc--server-last-reconnect-display-reset (current-buffer))) - -(defun erc--server-last-reconnect-display-reset (buffer) - "Deactivate `erc-auto-reconnect-display'." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (when erc--server-reconnect-display-timer - (cancel-timer erc--server-reconnect-display-timer) - (remove-hook 'erc-disconnected-hook - #'erc--server-last-reconnect-display-reset t) - (setq erc--server-reconnect-display-timer nil - erc--server-last-reconnect-count 0))))) - -(defconst erc--mode-line-process-reconnecting - '(:eval (erc-with-server-buffer - (and erc--server-reconnect-timer - (format ": reconnecting in %.1fs" - (- (timer-until erc--server-reconnect-timer - (current-time))))))) - "Mode-line construct showing seconds until next reconnect attempt. -Move point around to refresh.") - -(defun erc--cancel-auto-reconnect-timer () - (when erc--server-reconnect-timer - (cancel-timer erc--server-reconnect-timer) - (erc-display-message nil 'notice nil 'reconnect-canceled - ?u (buffer-name) - ?c (- (timer-until erc--server-reconnect-timer - (current-time)))) - (setq erc--server-reconnect-timer nil) - (erc-update-mode-line))) - -(defun erc-schedule-reconnect (buffer &optional incr) - "Create and return a reconnect timer for BUFFER. -When `erc-server-reconnect-attempts' is a number, increment -`erc-server-reconnect-count' by INCR unconditionally." - (let ((count (and (integerp erc-server-reconnect-attempts) - (- erc-server-reconnect-attempts - (cl-incf erc-server-reconnect-count (or incr 1))))) - (proc (buffer-local-value 'erc-server-process buffer))) - (erc-display-message nil '(notice error) buffer 'reconnecting - ?m erc-server-reconnect-timeout - ?i (if count erc-server-reconnect-count "N") - ?n (if count erc-server-reconnect-attempts "A")) - (set-process-sentinel proc #'ignore) - (delete-process proc) - (erc-update-mode-line) - (setq erc-server-reconnecting nil - erc--server-reconnect-timer - (run-at-time erc-server-reconnect-timeout nil - erc-server-reconnect-function buffer)))) - -(defun erc-process-sentinel-2 (event buffer) - "Called when `erc-process-sentinel-1' has detected an unexpected disconnect." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (let ((reconnect-p (erc--server-reconnect-p event)) message) - (setq message (if reconnect-p 'disconnected 'disconnected-noreconnect)) - (erc-display-message nil 'error (current-buffer) message) - (if (not reconnect-p) - ;; terminate, do not reconnect - (progn - (setq erc--server-reconnect-timer nil) - (erc-display-message nil 'error (current-buffer) - 'terminated ?e event) - (set-buffer-modified-p nil)) - ;; reconnect - (erc-schedule-reconnect buffer)))) - (erc-update-mode-line))) - -(defun erc-process-sentinel-1 (event buffer) - "Called when `erc-process-sentinel' has decided that we're disconnecting. -Determine whether user has quit or whether erc has been terminated. -Conditionally try to reconnect and take appropriate action." - (with-current-buffer buffer - (if erc-server-quitting - ;; normal quit - (progn - (erc-display-message nil 'error (current-buffer) 'finished) - ;; Update mode line indicators - (erc-update-mode-line) - ;; Kill server buffer if user wants it - (set-buffer-modified-p nil) - (defvar erc-kill-server-buffer-on-quit) - (when erc-kill-server-buffer-on-quit - (kill-buffer (current-buffer)))) - ;; unexpected disconnect - (erc-process-sentinel-2 event buffer)))) - -(defvar-local erc--hidden-prompt-overlay nil - "Overlay for hiding the prompt when disconnected.") - -(cl-defmethod erc--reveal-prompt () - (when erc--hidden-prompt-overlay - (delete-overlay erc--hidden-prompt-overlay) - (setq erc--hidden-prompt-overlay nil))) - -(cl-defmethod erc--conceal-prompt () - (when-let (((null erc--hidden-prompt-overlay)) - (ov (make-overlay erc-insert-marker (1- erc-input-marker) - nil 'front-advance))) - (defvar erc-prompt-hidden) - (overlay-put ov 'display erc-prompt-hidden) - (setq erc--hidden-prompt-overlay ov))) - -(defun erc--prompt-hidden-p () - (and (marker-position erc-insert-marker) - (eq (get-text-property erc-insert-marker 'erc-prompt) 'hidden))) - -(defun erc--unhide-prompt () - (remove-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert t) - (when (and (marker-position erc-insert-marker) - (marker-position erc-input-marker)) - (with-silent-modifications - (put-text-property erc-insert-marker (1- erc-input-marker) 'erc-prompt t) - (erc--reveal-prompt) - (run-hooks 'erc--refresh-prompt-hook)))) - -(defun erc--unhide-prompt-on-self-insert () - (when (and (eq this-command #'self-insert-command) - (or (eobp) (= (point) erc-input-marker))) - (erc--unhide-prompt))) - -(defun erc--hide-prompt (proc) - "Hide prompt in all buffers of server. -Change value of property `erc-prompt' from t to `hidden'." - (erc-with-all-buffers-of-server proc nil - (when (and erc-hide-prompt - (or (eq erc-hide-prompt t) - (memq (if erc--target - (if (erc--target-channel-p erc--target) - 'channel - 'query) - 'server) - erc-hide-prompt)) - (marker-position erc-insert-marker) - (marker-position erc-input-marker) - (get-text-property erc-insert-marker 'erc-prompt)) - (with-silent-modifications - (put-text-property erc-insert-marker (1- erc-input-marker) - 'erc-prompt 'hidden) - (erc--conceal-prompt) - (run-hooks 'erc--refresh-prompt-hook)) - (add-hook 'pre-command-hook #'erc--unhide-prompt-on-self-insert 80 t)))) - -(defun erc-process-sentinel (cproc event) - "Sentinel function for ERC process." - (let ((buf (process-buffer cproc))) - (when (buffer-live-p buf) - (with-current-buffer buf - (erc-log (format - "SENTINEL: proc: %S status: %S event: %S (quitting: %S)" - cproc (process-status cproc) event erc-server-quitting)) - (if (string-match "^open" event) - ;; newly opened connection (no wait) - (erc--register-connection) - ;; assume event is 'failed - (erc-with-all-buffers-of-server cproc nil - (setq erc-server-connected nil)) - (when erc-server-ping-handler - (progn (cancel-timer erc-server-ping-handler) - (setq erc-server-ping-handler nil))) - (run-hook-with-args 'erc-disconnected-hook - (erc-current-nick) (system-name) "") - (erc-with-all-buffers-of-server cproc (lambda () erc-channel-members) - (when (erc--target-channel-p erc--target) - (setf (erc--target-channel-joined-p erc--target) nil)) - (clrhash erc-channel-members)) - ;; Hide the prompt - (erc--hide-prompt cproc) - ;; Decide what to do with the buffer - ;; Restart if disconnected - (erc-process-sentinel-1 event buf)))))) - -;;;; Sending messages - -(defun erc-coding-system-for-target (target) - "Return the coding system or cons cell appropriate for TARGET. -This is determined via `erc-encoding-coding-alist' or -`erc-server-coding-system'." - (unless target (setq target (erc-default-target))) - (or (when target - (let ((case-fold-search t)) - (catch 'match - (dolist (pat erc-encoding-coding-alist) - (when (string-match (car pat) target) - (throw 'match (cdr pat))))))) - (and (functionp erc-server-coding-system) - (funcall erc-server-coding-system target)) - erc-server-coding-system)) - -(defun erc-decode-string-from-target (str target) - "Decode STR as appropriate for TARGET. -This is indicated by `erc-encoding-coding-alist', defaulting to the -value of `erc-server-coding-system'." - (unless (stringp str) - (setq str "")) - (let ((coding (erc-coding-system-for-target target))) - (when (consp coding) - (setq coding (cdr coding))) - (when (eq coding 'undecided) - (let ((codings (detect-coding-string str)) - (precedence erc-coding-system-precedence)) - (while (and precedence - (not (memq (car precedence) codings))) - (pop precedence)) - (when precedence - (setq coding (car precedence))))) - (decode-coding-string str coding t))) - -;; proposed name, not used by anything yet -(defun erc-send-line (text display-fn) - "Send TEXT to the current server. Wrapping and flood control apply. -Use DISPLAY-FN to show the results." - (mapc (lambda (line) - (erc-server-send line) - (funcall display-fn)) - (erc-split-line text))) - -;; From Circe, with modifications -(defun erc-server-send (string &optional force target) - "Send STRING to the current server. -When FORCE is non-nil, bypass flood protection so that STRING is -sent directly without modifying the queue. When FORCE is the -symbol `no-penalty', exempt this round from accumulating a -timeout penalty and schedule it to run ASAP instead of blocking. - -If TARGET is specified, look up encoding information for that -channel in `erc-encoding-coding-alist' or -`erc-server-coding-system'. - -See `erc-server-flood-margin' for an explanation of the flood -protection algorithm." - (erc--server-send string force target)) - -(cl-defmethod erc--server-send (string force target) - "Encode and send STRING to `erc-server-process'. -Expect STRING, FORCE, and TARGET to originate from `erc-server-send'." - (erc-log (concat "erc-server-send: " string "(" (buffer-name) ")")) - (setq erc-server-last-sent-time (erc-current-time)) - (let ((encoding (erc-coding-system-for-target target))) - (when (consp encoding) - (setq encoding (car encoding))) - (if (erc-server-process-alive) - (erc-with-server-buffer - (let ((str (concat string "\r\n"))) - (if force - (progn - (unless (eq force 'no-penalty) - (cl-incf erc-server-flood-last-message - erc-server-flood-penalty)) - (erc-log-irc-protocol str 'outbound) - (condition-case nil - (progn - ;; Set encoding just before sending the string - (when (fboundp 'set-process-coding-system) - (set-process-coding-system erc-server-process - 'raw-text encoding)) - (if (and (eq force 'no-penalty)) - (run-at-time nil nil #'process-send-string - erc-server-process str) - (process-send-string erc-server-process str))) - ;; See `erc-server-send-queue' for full - ;; explanation of why we need this condition-case - (error nil))) - (setq erc-server-flood-queue - (append erc-server-flood-queue - (list (cons str encoding)))) - (run-at-time nil nil #'erc-server-send-queue (current-buffer)))) - t) - (message "ERC: No process running") - nil))) - -(defun erc-server-send-ping (buf) - "Send a ping to the IRC server buffer in BUF. -Additionally, detect whether the IRC process has hung." - (if (and (buffer-live-p buf) - (with-current-buffer buf - erc-server-last-received-time)) - (with-current-buffer buf - (if (and erc-server-send-ping-timeout - (time-less-p - erc-server-send-ping-timeout - (time-since erc-server-last-received-time))) - (progn - ;; if the process is hung, kill it - (setq erc-server-timed-out t) - (delete-process erc-server-process)) - (erc-server-send (format "PING %.0f" (erc-current-time))))) - ;; remove timer if the server buffer has been killed - (let ((timer (assq buf erc-server-ping-timer-alist))) - (when timer - (cancel-timer (cdr timer)) - (setcdr timer nil))))) - -;; From Circe -(defun erc-server-send-queue (buffer) - "Send messages in `erc-server-flood-queue'. -See `erc-server-flood-margin' for an explanation of the flood -protection algorithm." - (when (buffer-live-p buffer) - (with-current-buffer buffer - (let ((now (current-time))) - (when erc-server-flood-timer - (cancel-timer erc-server-flood-timer) - (setq erc-server-flood-timer nil)) - (when (time-less-p erc-server-flood-last-message now) - (setq erc-server-flood-last-message (erc-emacs-time-to-erc-time now))) - (while (and erc-server-flood-queue - (time-less-p erc-server-flood-last-message - (time-add now erc-server-flood-margin))) - (let ((msg (caar erc-server-flood-queue)) - (encoding (cdar erc-server-flood-queue))) - (setq erc-server-flood-queue (cdr erc-server-flood-queue) - erc-server-flood-last-message - (+ erc-server-flood-last-message - erc-server-flood-penalty)) - (erc-log-irc-protocol msg 'outbound) - (erc-log (concat "erc-server-send-queue: " - msg "(" (buffer-name buffer) ")")) - (when (erc-server-process-alive) - (condition-case nil - ;; Set encoding just before sending the string - (progn - (when (fboundp 'set-process-coding-system) - (set-process-coding-system erc-server-process - 'raw-text encoding)) - (process-send-string erc-server-process msg)) - ;; Sometimes the send can occur while the process is - ;; being killed, which results in a weird SIGPIPE error. - ;; Catch this and ignore it. - (error nil))))) - (when erc-server-flood-queue - (setq erc-server-flood-timer - (run-at-time (+ 0.2 erc-server-flood-penalty) - nil #'erc-server-send-queue buffer))))))) - -(defun erc-message (message-command line &optional force) - "Send LINE, possibly expanding a target specifier beforehand. -Expect MESSAGE-COMMAND to be an IRC command with a single -positional target parameter followed by a trailing parameter. - -If the target is \",\", the last person you've got a message from will -be used. If the target is \".\", the last person you've sent a message -to will be used." - (cond - ((string-match "^\\s-*\\(\\S-+\\) ?\\(.*\\)" line) - (let* ((tgt (match-string 1 line)) - (s (match-string 2 line)) - (server-buffer (erc-server-buffer)) - (peers (buffer-local-value 'erc-server-last-peers server-buffer))) - (erc-log (format "cmd: MSG(%s): [%s] %s" message-command tgt s)) - (cond - ((string= tgt ",") - (setq tgt (car peers))) - ((string= tgt ".") - (setq tgt (cdr peers)))) - (cond - (tgt - (with-current-buffer server-buffer - (setq erc-server-last-peers (cons (car peers) tgt))) - (erc-server-send (format "%s %s :%s" message-command tgt s) - force)) - (t - (erc-display-message nil 'error (current-buffer) 'no-target)))) - t) - (t nil))) - -;;; CTCP - -(defun erc-send-ctcp-message (tgt l &optional force) - "Send CTCP message L to TGT. - -If TGT is nil the message is not sent. -The command must contain neither a prefix nor a trailing `\\n'. - -See also `erc-server-send'." - (let ((l (erc-upcase-first-word l))) - (cond - (tgt - (erc-log (format "erc-send-CTCP-message: [%s] %s" tgt l)) - (erc-server-send (format "PRIVMSG %s :\C-a%s\C-a" tgt l) - force))))) - -(defun erc-send-ctcp-notice (tgt l &optional force) - "Send CTCP notice L to TGT. - -If TGT is nil the message is not sent. -The command must contain neither a prefix nor a trailing `\\n'. - -See also `erc-server-send'." - (let ((l (erc-upcase-first-word l))) - (cond - (tgt - (erc-log (format "erc-send-CTCP-notice: [%s] %s" tgt l)) - (erc-server-send (format "NOTICE %s :\C-a%s\C-a" tgt l) - force))))) - -;;;; Handling responses - -(defcustom erc-tags-format 'overridable - "Shape of the `tags' alist in `erc-response' objects. -When set to `legacy', pre-5.5 parsing behavior takes effect for -the tags portion of every message. The resulting alist contains -conses of the form (STRING . LIST), in which LIST is comprised of -at most one, possibly empty string. When set to nil, ERC only -parses tags if an active module defines an implementation. It -otherwise ignores them. In such cases, each alist element is a -cons of a symbol and an optional, nonempty string. - -With the default value of `overridable', ERC behaves as it does -with `legacy' except that it emits a warning whenever first -encountering a message containing tags in a given Emacs session. -But it only does so when a module implementing overriding, -non-legacy behavior isn't already active in the current network -context. - -Note that future bundled modules providing IRCv3 functionality -will not be compatible with the legacy format. User code should -eventually transition to expecting this \"5.5+ variant\" and set -this option to nil." - :package-version '(ERC . "5.5") - :type '(choice (const nil) - (const legacy) - (const overridable))) - -(defun erc-parse-tags (string) - "Parse IRCv3 tags list in STRING to a (tag . value) alist." - (erc--parse-message-tags string)) - -(defun erc--parse-tags (string) - (let ((tags) - (tag-strings (split-string string ";"))) - (dolist (tag-string tag-strings tags) - (let ((pair (split-string tag-string "="))) - (push (if (consp pair) - pair - `(,pair)) - tags))))) - -;; A benefit of this function being internal is not having to define a -;; separate method just to ensure an `erc-tags-format' value of -;; `legacy' always wins. A downside is that module code must take -;; care to preserve that promise manually. - -(cl-defgeneric erc--parse-message-tags (string) - "Parse STRING into an alist of (TAG . VALUE) conses. -Expect TAG to be a symbol and VALUE nil or a nonempty string. -Don't split composite raw-input values containing commas; -instead, leave them as a single string." - (when erc-tags-format - (unless (or (eq erc-tags-format 'legacy) - (get 'erc-parse-tags 'erc-v3-warned-p)) - (put 'erc-parse-tags 'erc-v3-warned-p t) - (display-warning - 'erc - (concat - "Legacy ERC tags behavior is currently in effect, but other modules," - " including those bundled with ERC, may override this in future" - " releases. See `erc-tags-format' for more info."))) - (erc--parse-tags string))) - -(defun erc-parse-server-response (proc string) - "Parse and act upon a complete line from an IRC server. -PROC is the process (connection) from which STRING was received. -PROCs `process-buffer' is `current-buffer' when this function is called." - (unless (string= string "") ;; Ignore empty strings - (save-match-data - (let* ((tag-list (when (eq (aref string 0) ?@) - (substring string 1 - (string-search " " string)))) - (msg (make-erc-response :unparsed string :tags - (when tag-list - (erc--parse-message-tags tag-list)))) - (string (if tag-list - (substring string (+ 1 (string-search " " string))) - string)) - (posn (if (eq (aref string 0) ?:) - (string-search " " string) - 0))) - - (setf (erc-response.sender msg) - (if (eq posn 0) - erc-session-server - (substring string 1 posn))) - - (setf (erc-response.command msg) - (let* ((bposn (string-match "[^ \n]" string posn)) - (eposn (string-search " " string bposn))) - (setq posn (and eposn - (string-match "[^ \n]" string eposn))) - (substring string bposn eposn))) - - (while (and posn - (not (eq (aref string posn) ?:))) - (push (let* ((bposn posn) - (eposn (string-search " " string bposn))) - (setq posn (and eposn - (string-match "[^ \n]" string eposn))) - (substring string bposn eposn)) - (erc-response.command-args msg))) - (when posn - (let ((str (substring string (1+ posn)))) - (push str (erc-response.command-args msg)))) - - (setf (erc-response.contents msg) - (car (erc-response.command-args msg))) - - (setf (erc-response.command-args msg) - (nreverse (erc-response.command-args msg))) - - (erc-decode-parsed-server-response msg) - - (erc-handle-parsed-server-response proc msg))))) - -(defun erc-decode-parsed-server-response (parsed-response) - "Decode a pre-parsed PARSED-RESPONSE before it can be handled. - -If there is a channel name in `erc-response.command-args', decode -`erc-response' according to this channel name and -`erc-encoding-coding-alist', or use `erc-server-coding-system' -for decoding." - (let ((args (erc-response.command-args parsed-response)) - (decode-target nil) - (decoded-args ())) - ;; FIXME this should stop after the first match. - (dolist (arg args nil) - (when (string-match "^[#&].*" arg) - (setq decode-target arg))) - (when (stringp decode-target) - ;; FIXME `decode-target' should be passed as TARGET. - (setq decode-target (erc-decode-string-from-target decode-target nil))) - (setf (erc-response.unparsed parsed-response) - (erc-decode-string-from-target - (erc-response.unparsed parsed-response) - decode-target)) - (setf (erc-response.sender parsed-response) - (erc-decode-string-from-target - (erc-response.sender parsed-response) - decode-target)) - (setf (erc-response.command parsed-response) - (erc-decode-string-from-target - (erc-response.command parsed-response) - decode-target)) - (dolist (arg (nreverse args) nil) - (push (erc-decode-string-from-target arg decode-target) - decoded-args)) - (setf (erc-response.command-args parsed-response) decoded-args) - (setf (erc-response.contents parsed-response) - (erc-decode-string-from-target - (erc-response.contents parsed-response) - decode-target)))) - -(defun erc-handle-parsed-server-response (process parsed-response) - "Handle a pre-parsed PARSED-RESPONSE from PROCESS. - -Hands off to helper functions via `erc-call-hooks'." - (if (member (erc-response.command parsed-response) - erc-server-prevent-duplicates) - (let ((m (erc-response.unparsed parsed-response))) - ;; duplicate suppression - (if (time-less-p (or (gethash m erc-server-duplicates) 0) - (time-since erc-server-duplicate-timeout)) - (erc-call-hooks process parsed-response)) - (puthash m (erc-current-time) erc-server-duplicates)) - ;; Hand off to the relevant handler. - (erc-call-hooks process parsed-response))) - -(defun erc-get-hook (command) - "Return the hook variable associated with COMMAND. - -See also `erc-server-responses'." - (gethash (format (if (numberp command) "%03i" "%s") command) - erc-server-responses)) - -(defvar erc--parsed-response nil) - -(defun erc-call-hooks (process message) - "Call hooks associated with MESSAGE in PROCESS. - -Finds hooks by looking in the `erc-server-responses' hash table." - (let ((erc--parsed-response message) - (erc--msg-prop-overrides erc--msg-prop-overrides) - (hook (or (erc-get-hook (erc-response.command message)) - 'erc-default-server-functions))) - (run-hook-with-args-until-success hook process message) - ;; Some handlers, like `erc-cmd-JOIN', open new targets without - ;; saving excursion, and `erc-open' sets the current buffer. - (erc-with-server-buffer - (run-hook-with-args 'erc-timer-hook (erc-current-time))))) - -(defun erc-handle-unknown-server-response (proc parsed) - "Display unknown server response's message." - (let ((line (concat (erc-response.sender parsed) - " " - (erc-response.command parsed) - " " - (mapconcat #'identity (erc-response.command-args parsed) - " ")))) - (erc-display-message parsed 'notice proc line))) - - -(cl-defmacro define-erc-response-handler ((name &rest aliases) - &optional extra-fn-doc extra-var-doc - &rest fn-body) - "Define an ERC handler hook/function pair. -NAME is the response name as sent by the server (see the IRC RFC for -meanings). - -This creates: - - a hook variable `erc-server-NAME-functions' initialized to - `erc-server-NAME'. - - a function `erc-server-NAME' with body FN-BODY. - -\(Note that here, NAME merely refers to the parameter NAME rather than -an actual IRC response or server-sent command.) - -If ALIASES is non-nil, each alias in ALIASES is `defalias'ed to -`erc-server-NAME'. -Alias hook variables are created as `erc-server-ALIAS-functions' and -initialized to the same default value as `erc-server-NAME-functions'. - -ERC uses FN-BODY as the body of the default response handler -`erc-server-NAME', which handles all incoming IRC \"NAME\" responses, -unless overridden (see below). ERC calls the function with two -arguments, PROC and PARSED, whose symbols (lowercase) are bound to the -current `erc-server-process' and `erc-response' instance within FN-BODY. -Implementers should take care not to shadow them inadvertently. In all -cases, FN-BODY should return nil to allow third parties to run code -after `erc-server-NAME' returns. For historical reasons, ERC does not -currently enforce this, however future versions very well may. - -If EXTRA-FN-DOC is non-nil, it is inserted at the beginning of the -defined function's docstring. - -If EXTRA-VAR-DOC is non-nil, it is inserted at the beginning of the -defined variable's docstring. - -As an example: - - (define-erc-response-handler (311 WHOIS WI) - \"Some non-generic function documentation.\" - \"Some non-generic variable documentation.\" - (do-stuff-with-whois proc parsed)) - -Would expand to: - - (prog2 - (defvar erc-server-311-functions \\='erc-server-311 - \"Some non-generic variable documentation. - - Hook called upon receiving a 311 server response. - Each function is called with two arguments, the process associated - with the response and the parsed response. - See also `erc-server-311'.\") - - (defun erc-server-311 (proc parsed) - \"Some non-generic function documentation. - - Handler for a 311 server response. - PROC is the server process which returned the response. - PARSED is the actual response as an `erc-response' struct. - If you want to add responses don't modify this function, but rather - add things to `erc-server-311-functions' instead.\" - (do-stuff-with-whois proc parsed)) - - (puthash \"311\" \\='erc-server-311-functions erc-server-responses) - (puthash \"WHOIS\" \\='erc-server-WHOIS-functions erc-server-responses) - (puthash \"WI\" \\='erc-server-WI-functions erc-server-responses) - - (defalias \\='erc-server-WHOIS \\='erc-server-311) - (defvar erc-server-WHOIS-functions \\='erc-server-311 - \"Some non-generic variable documentation. - - Hook called upon receiving a WHOIS server response. - - Each function is called with two arguments, the process associated - with the response and the parsed response. If the function returns - non-nil, stop processing the hook. Otherwise, continue. - - See also `erc-server-311'.\") - - (defalias \\='erc-server-WI \\='erc-server-311) - (defvar erc-server-WI-functions \\='erc-server-311 - \"Some non-generic variable documentation. - - Hook called upon receiving a WI server response. - Each function is called with two arguments, the process associated - with the response and the parsed response. If the function returns - non-nil, stop processing the hook. Otherwise, continue. - - See also `erc-server-311'.\")) - - Note that while all ALIASES share the same handler function, each gets - its own distinct hook variable. The default value of these variables - may be a list or a function. Robust code should handle both. - -\(fn (NAME &rest ALIASES) &optional EXTRA-FN-DOC EXTRA-VAR-DOC &rest FN-BODY)" - (declare (debug (&define [&name "erc-response-handler@" - ;; No `def-edebug-elem-spec' in 27. - ([&or integerp symbolp] - &rest [&or integerp symbolp])] - &optional sexp sexp def-body)) - (doc-string 2) - (indent defun)) - (if (numberp name) (setq name (intern (format "%03i" name)))) - (setq aliases (mapcar (lambda (a) - (if (numberp a) - (format "%03i" a) - a)) - aliases)) - (let* ((hook-name (intern (format "erc-server-%s-functions" name))) - (fn-name (intern (format "erc-server-%s" name))) - (hook-doc (format "\ -%sHook called upon receiving a %%s server response. -Each function is called with two arguments, the process associated -with the response and the parsed response. If the function returns -non-nil, stop processing the hook. Otherwise, continue. - -See also `%s'." - (if extra-var-doc - (concat extra-var-doc "\n\n") - "") - fn-name)) - (fn-doc (format "\ -%sHandler for a %s server response. -PROC is the server process which returned the response. -PARSED is the actual response as an `erc-response' struct. -If you want to add responses don't modify this function, but rather -add things to `%s' instead." - (if extra-fn-doc - (concat extra-fn-doc "\n\n") - "") - name hook-name)) - (fn-alternates - (cl-loop for alias in aliases - collect (intern (format "erc-server-%s" alias)))) - (var-alternates - (cl-loop for alias in aliases - collect (intern (format "erc-server-%s-functions" alias))))) - `(prog2 - ;; Normal hook variable. The variable may already have a - ;; value at this point, so I default to nil, and (add-hook) - ;; unconditionally - (defvar ,hook-name nil ,(format hook-doc name)) - (add-hook ',hook-name #',fn-name) - ;; Handler function - (defun ,fn-name (proc parsed) - ,fn-doc - (ignore proc parsed) - ,@fn-body) - - ;; Make find-function and find-variable find them - (put ',fn-name 'definition-name ',name) - (put ',hook-name 'definition-name ',name) - - ;; Hash table map of responses to hook variables - ,@(cl-loop for response in (cons name aliases) - for var in (cons hook-name var-alternates) - collect `(puthash ,(format "%s" response) ',var - erc-server-responses)) - ;; Alternates. - ;; Functions are defaliased, hook variables are defvared so we - ;; can add hooks to one alias, but not another. - ,@(cl-loop for fn in fn-alternates - for var in var-alternates - for a in aliases - nconc (list `(defalias ',fn #',fn-name) - `(defvar ,var #',fn-name ,(format hook-doc a)) - `(put ',var 'definition-name ',hook-name)))))) - -(define-erc-response-handler (ERROR) - "Handle an ERROR command from the server." nil - (setq erc-server-error-occurred t) - (erc-display-message - parsed 'error nil 'ERROR - ?s (erc-response.sender parsed) ?c (erc-response.contents parsed))) - -(define-erc-response-handler (INVITE) - "Handle invitation messages." - nil - (let ((target (car (erc-response.command-args parsed))) - (chnl (erc-response.contents parsed))) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (defvar erc-invitation) - (setq erc-invitation chnl) - (when (string= target (erc-current-nick)) - (erc-display-message - parsed 'notice 'active - 'INVITE ?n nick ?u login ?h host ?c chnl))))) - -(cl-defmethod erc--server-determine-join-display-context (_channel alist) - "Determine `erc--display-context' for JOINs." - (if (assq 'erc-buffer-display alist) - alist - `((erc-buffer-display . JOIN) ,@alist))) - -(define-erc-response-handler (JOIN) - "Handle join messages." - nil - (let ((chnl (erc-response.contents parsed)) - (buffer nil)) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - ;; strip the stupid combined JOIN facility (IRC 2.9) - (if (string-match "^\\(.*\\)\^g.*$" chnl) - (setq chnl (match-string 1 chnl))) - (save-excursion - (let ((args (cond - ;; If I have joined a channel - ((erc-current-nick-p nick) - (let ((erc--display-context - (erc--server-determine-join-display-context - chnl erc--display-context))) - (setq buffer (erc--open-target chnl))) - (when buffer - (set-buffer buffer) - (with-suppressed-warnings - ((obsolete erc-add-default-channel)) - (erc-add-default-channel chnl)) - (setf (erc--target-channel-joined-p erc--target) t) - (erc-server-send (format "MODE %s" chnl))) - (erc-with-buffer (chnl proc) - (erc-channel-begin-receiving-names)) - (erc-update-mode-line) - (run-hooks 'erc-join-hook) - (list 'JOIN-you ?c chnl)) - (t - (setq buffer (erc-get-buffer chnl proc)) - (list 'JOIN ?n nick ?u login ?h host ?c chnl))))) - (when buffer (set-buffer buffer)) - (erc-update-channel-member chnl nick nick t nil nil nil nil nil host login) - (unless (erc-current-nick-p nick) - (erc--ensure-query-member nick)) - ;; on join, we want to stay in the new channel buffer - ;;(set-buffer ob) - (apply #'erc-display-message parsed 'notice buffer args)))))) - -(define-erc-response-handler (KICK) - "Handle kick messages received from the server." nil - (let* ((ch (nth 0 (erc-response.command-args parsed))) - (tgt (nth 1 (erc-response.command-args parsed))) - (reason (erc-trim-string (erc-response.contents parsed))) - (buffer (erc-get-buffer ch proc))) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (cond - ((string= tgt (erc-current-nick)) - (erc-display-message - parsed 'notice buffer - 'KICK-you ?n nick ?u login ?h host ?c ch ?r reason) - (run-hook-with-args 'erc-kick-hook buffer) - (erc-with-buffer - (buffer) - (erc--remove-channel-users-but tgt)) - (with-suppressed-warnings ((obsolete erc-delete-default-channel)) - (erc-delete-default-channel ch buffer)) - (erc-update-mode-line buffer)) - ((string= nick (erc-current-nick)) - (erc-display-message - parsed 'notice buffer - 'KICK-by-you ?k tgt ?c ch ?r reason) - (erc-remove-channel-member buffer tgt)) - (t (erc-display-message - parsed 'notice buffer - 'KICK ?k tgt ?n nick ?u login ?h host ?c ch ?r reason) - (erc-remove-channel-member buffer tgt))))) - nil) - -(define-erc-response-handler (MODE) - "Handle server mode changes." nil - (let ((tgt (car (erc-response.command-args parsed))) - (mode (mapconcat #'identity (cdr (erc-response.command-args parsed)) - " "))) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (erc-log (format "MODE: %s -> %s: %s" nick tgt mode)) - ;; dirty hack - (let ((buf (cond ((erc-channel-p tgt) - (erc-get-buffer tgt proc)) - ((string= tgt (erc-current-nick)) nil) - ((erc-active-buffer) (erc-active-buffer)) - (t (erc-get-buffer tgt))))) - (with-current-buffer (or buf - (current-buffer)) - (erc--update-modes (cdr (erc-response.command-args parsed)))) - (if (or (string= login "") (string= host "")) - (erc-display-message parsed 'notice buf - 'MODE-nick ?n nick - ?t tgt ?m mode) - (erc-display-message parsed 'notice buf - 'MODE ?n nick ?u login - ?h host ?t tgt ?m mode))))) - nil) - -(defun erc--wrangle-query-buffers-on-nick-change (old new) - "Create or reuse a query buffer for NEW nick after considering OLD nick. -Return a list of buffers in which to announce the change." - ;; Note that `new-buffer' may be older than `old-buffer', e.g., if - ;; the query target is switching to a previously used nick. - (let ((new-buffer (erc-get-buffer new erc-server-process)) - (old-buffer (erc-get-buffer old erc-server-process)) - (selfp (erc-current-nick-p old)) ; e.g., for note taking, etc. - buffers) - (when new-buffer - (push new-buffer buffers)) - (when old-buffer - (push old-buffer buffers) - ;; Ensure the new nick is absent from the old query. - (unless selfp - (erc-remove-channel-member old-buffer old)) - (when (or selfp (null new-buffer)) - (let ((target (erc--target-from-string new)) - (id (erc-networks--id-given erc-networks--id))) - (with-current-buffer old-buffer - (setq erc-default-recipients (cons new - (cdr erc-default-recipients)) - erc--target target)) - (setq new-buffer (erc-get-buffer-create erc-session-server - erc-session-port - nil target id))))) - (when new-buffer - (with-current-buffer new-buffer - (erc-update-mode-line))) - buffers)) - -(define-erc-response-handler (NICK) - "Handle nick change messages." nil - (let ((nn (erc-response.contents parsed)) - bufs) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (setq bufs (erc-buffer-list-with-nick nick proc)) - (erc-log (format "NICK: %s -> %s" nick nn)) - ;; if we had a query with this user, make sure future messages will be - ;; sent to the correct nick. also add to bufs, since the user will want - ;; to see the nick change in the query, and if it's a newly begun query, - ;; erc-channel-users won't contain it - ;; - ;; Possibly still relevant: bug#12002 - (dolist (buf (erc--wrangle-query-buffers-on-nick-change nick nn)) - (cl-pushnew buf bufs)) - (erc-update-user-nick nick nn host login) - (cond - ((string= nick (erc-current-nick)) - (cl-pushnew (erc-server-buffer) bufs) - ;; Show message in all query buffers. - (setq bufs (append (erc--query-list) bufs)) - (erc-set-current-nick nn) - ;; Rename session, possibly rename server buf and all targets - (when erc-server-connected - (erc-networks--id-reload erc-networks--id proc parsed)) - (erc-update-mode-line) - (setq erc-nick-change-attempt-count 0) - (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick))) - (erc-display-message - parsed 'notice bufs - 'NICK-you ?n nick ?N nn) - (run-hook-with-args 'erc-nick-changed-functions nn nick)) - (t - (when erc-server-connected - (erc-networks--id-reload erc-networks--id proc parsed) - (erc--ensure-query-member nn)) - (erc-handle-user-status-change 'nick (list nick login host) (list nn)) - (erc-display-message parsed 'notice bufs 'NICK ?n nick - ?u login ?h host ?N nn)))))) - -(define-erc-response-handler (PART) - "Handle part messages." nil - (let* ((chnl (car (erc-response.command-args parsed))) - (reason (erc-trim-string (erc-response.contents parsed))) - (buffer (erc-get-buffer chnl proc))) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - ;; When `buffer' is nil, `erc-remove-channel-member' and - ;; `erc-remove-channel-users' do almost nothing, and the message - ;; is displayed in the server buffer. - (erc-display-message parsed 'notice buffer - 'PART ?n nick ?u login - ?h host ?c chnl ?r (or reason "")) - (cond - ((string= nick (erc-current-nick)) - (run-hook-with-args 'erc-part-hook buffer) - (erc-with-buffer - (buffer) - (erc--remove-channel-users-but nick)) - (with-suppressed-warnings ((obsolete erc-delete-default-channel)) - (erc-delete-default-channel chnl buffer)) - (erc-update-mode-line buffer) - (defvar erc-kill-buffer-on-part) - (when (and erc-kill-buffer-on-part buffer) - (defvar erc-killing-buffer-on-part-p) - (let ((erc-killing-buffer-on-part-p t)) - (kill-buffer buffer)))) - (t (erc-remove-channel-member buffer nick))))) - nil) - -(define-erc-response-handler (PING) - "Handle ping messages." nil - (let ((pinger (car (erc-response.command-args parsed)))) - (erc-log (format "PING: %s" pinger)) - ;; ping response to the server MUST be forced, or you can lose big - (erc-server-send (format "PONG :%s" pinger) 'no-penalty) - (when erc-verbose-server-ping - (erc-display-message - parsed 'error proc - 'PING ?s (erc-time-diff erc-server-last-ping-time (erc-current-time)))) - (setq erc-server-last-ping-time (erc-current-time))) - nil) - -(define-erc-response-handler (PONG) - "Handle pong messages." nil - (let ((time (string-to-number (erc-response.contents parsed)))) - (when (> time 0) - (setq erc-server-lag (erc-time-diff time nil)) - (when erc-verbose-server-ping - (erc-display-message - parsed 'notice proc 'PONG - ?h (car (erc-response.command-args parsed)) ?i erc-server-lag - ?s (if (/= erc-server-lag 1) "s" ""))) - (erc-update-mode-line)))) - -(defun erc--statusmsg-target (target) - "Return actual target from given TARGET if it has a leading prefix char." - (and-let* ((erc-ensure-target-buffer-on-privmsg) - ((not (eq erc-ensure-target-buffer-on-privmsg 'status))) - ((not (erc-channel-p target))) - (chars (erc--get-isupport-entry 'STATUSMSG 'single)) - ((string-search (string (aref target 0)) chars)) - (trimmed (substring target 1)) - ((erc-channel-p trimmed))) - trimmed)) - -;; Moved to this file from erc.el in ERC 5.6. -(defvar-local erc-current-message-catalog 'english - "Current language or context catalog for formatting inserted messages. -See `erc-format-message'.") - -;; This variable can be made public if the current design proves -;; sufficient. -(defvar erc--message-speaker-catalog '-speaker - "The \"speaker\" catalog symbol used to format PRIVMSGs and NOTICEs. - -This symbol defines a \"catalog\" of variables and functions -whose names reflect their membership via a corresponding CATALOG -component, as in \"erc-message-CATALOG-KEY\". Here, KEY refers -to a common set of interface members (variables or functions), -that an implementer must define: - -- `statusmsg' and `statusmsg-input': PRIVMSGs whose target is a - status-prefixed channel; the latter is the \"echoed\" version - -- `chan-privmsg', `query-privmsg', `chan-notice', `query-notice': - standard chat messages traditionally prefixed by a - indicating the message's \"speaker\" - -- `input-chan-privmsg', `input-query-privmsg', `input-query-notice', - `input-chan-notice': \"echoed\" versions of the above - -- `ctcp-action', `ctcp-action-input', `ctcp-action-statusmsg', - `ctcp-action-statusmsg-input': \"CTCP ACTION\" versions of the - above - -The other part of this interface is the per-key collection of -`format-spec' parameters members must support. For simplicity, -this catalog currently defines a common set for all keys, some of -which may be assigned the empty string when not applicable: - - %n - nickname - %m - message body - %p - nickname's status prefix (when applicable) - %s - current target's STATUSMSG prefix (when applicable) - -As an added means of communicating with various modules, if this -catalog's symbol has the property `erc--msg-prop-overrides', -consumers calling `erc-display-message' will see the value added -to the `erc--msg-props' \"environment\" in modification hooks, -like `erc-insert-modify-hook'.") - -(defvar erc--speaker-status-prefix-wanted-p (gensym "erc-") - "Sentinel to detect whether `erc-format-@nick' has just run.") - -(define-erc-response-handler (PRIVMSG NOTICE) - "Handle private messages, including messages in channels." nil - (let ((sender-spec (erc-response.sender parsed)) - (cmd (erc-response.command parsed)) - (tgt (car (erc-response.command-args parsed))) - (msg (erc-response.contents parsed))) - (defvar erc-minibuffer-ignored) - (defvar erc-ignore-list) - (defvar erc-ignore-reply-list) - (if (or (and erc-ignore-list (erc-ignored-user-p sender-spec)) - (and erc-ignore-reply-list (erc-ignored-reply-p msg tgt proc))) - (when erc-minibuffer-ignored - (message "Ignored %s from %s to %s" cmd sender-spec tgt)) - (let* ((sndr (erc-parse-user sender-spec)) - (nick (nth 0 sndr)) - (login (nth 1 sndr)) - (host (nth 2 sndr)) - (msgp (string= cmd "PRIVMSG")) - (noticep (string= cmd "NOTICE")) - ;; S.B. downcase *both* tgt and current nick - (medown (erc-downcase (erc-current-nick))) - (inputp (string= medown (erc-downcase nick))) - (privp (string= (erc-downcase tgt) medown)) - (erc--display-context `((erc-buffer-display . ,(intern cmd)) - ,@erc--display-context)) - (erc--msg-prop-overrides `((erc--tmp) ,@erc--msg-prop-overrides)) - (erc--speaker-status-prefix-wanted-p nil) - (erc-current-message-catalog erc--message-speaker-catalog) - ;; - finalize buffer statusmsg cmem-prefix fnick) - (setq buffer (erc-get-buffer (if privp nick tgt) proc)) - ;; Even worth checking for empty target here? (invalid anyway) - (unless (or buffer noticep (string-empty-p tgt) (eq ?$ (aref tgt 0)) - (erc-is-message-ctcp-and-not-action-p msg)) - (defvar erc-receive-query-display) - (defvar erc-receive-query-display-defer) - (if privp - (when-let ((erc-join-buffer - (or (and (not erc-receive-query-display-defer) - erc-receive-query-display) - (and erc-ensure-target-buffer-on-privmsg - (or erc-receive-query-display - erc-join-buffer))))) - (push `(erc-receive-query-display . ,(intern cmd)) - erc--display-context) - (setq buffer (erc--open-target nick))) - (cond - ;; Target is a channel and contains leading @+ chars. - ((and-let* ((trimmed(erc--statusmsg-target tgt))) - (setq buffer (erc-get-buffer trimmed proc) - statusmsg (and buffer (substring tgt 0 1))))) - ;; A channel buffer has been killed but is still joined. - (erc-ensure-target-buffer-on-privmsg - (setq buffer (erc--open-target tgt)))))) - (when buffer - (with-current-buffer buffer - (when privp - (erc--unhide-prompt) - ;; Remove untracked query partners after display. - (defvar erc--decouple-query-and-channel-membership-p) - (unless (or erc--decouple-query-and-channel-membership-p - (erc--get-server-user nick)) - (setq finalize (lambda () - (erc-remove-channel-member buffer nick))))) - (erc-update-channel-member (if privp nick tgt) nick nick - privp nil nil nil nil nil host login nil nil t) - (defvar erc--cmem-from-nick-function) - (defvar erc-format-nick-function) - (defvar erc-show-speaker-membership-status) - (defvar erc-speaker-from-channel-member-function) - (let ((cdata (funcall erc--cmem-from-nick-function - (erc-downcase nick) sndr parsed))) - (setq fnick (funcall erc-speaker-from-channel-member-function - (car cdata) (cdr cdata)) - cmem-prefix (and (or erc--speaker-status-prefix-wanted-p - erc-show-speaker-membership-status - inputp) - (cdr cdata)))))) - (if (erc-is-message-ctcp-p msg) - (if noticep - (erc-process-ctcp-reply proc parsed nick login host - (match-string 1 msg)) - (setq parsed (erc--ctcp-response-from-parsed - :parsed parsed :buffer buffer :statusmsg statusmsg - :prefix cmem-prefix :dispname fnick)) - (erc-process-ctcp-query proc parsed nick login host)) - (setq erc-server-last-peers (cons nick (cdr erc-server-last-peers))) - (with-current-buffer (or buffer (current-buffer)) - ;; Re-bind in case either buffer has a local value. - (let ((erc-current-message-catalog erc--message-speaker-catalog) - (msg-args (erc--determine-speaker-message-format-args - nick msg privp msgp inputp statusmsg - cmem-prefix fnick))) - (if (or msgp (not privp)) - ;; This is a PRIVMSG or a NOTICE to a channel. - (apply #'erc-display-message parsed nil buffer msg-args) - ;; This is a NOTICE directed at the client's current nick. - (push (cons 'erc--msg (car msg-args)) erc--msg-prop-overrides) - (let ((fmtmsg (apply #'erc-format-message msg-args))) - (run-hook-with-args 'erc-echo-notice-always-hook - fmtmsg parsed buffer nick) - (run-hook-with-args-until-success - 'erc-echo-notice-hook fmtmsg parsed buffer nick))))) - (when finalize (funcall finalize))) - nil)))) - -(define-erc-response-handler (QUIT) - "Another user has quit IRC." nil - (let ((reason (erc-response.contents parsed)) - (erc--msg-prop-overrides erc--msg-prop-overrides) - bufs) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (setq bufs (erc-buffer-list-with-nick nick proc)) - (when (erc-current-nick-p nick) - (setq bufs (append (erc--query-list) bufs)) - (push '(erc--skip . (track)) erc--msg-prop-overrides)) - (setq reason (erc-wash-quit-reason reason nick login host)) - (erc-display-message parsed 'notice bufs - 'QUIT ?n nick ?u login - ?h host ?r reason) - (erc-remove-user nick))) - nil) - -(define-erc-response-handler (TOPIC) - "The channel topic has changed." nil - (let* ((ch (car (erc-response.command-args parsed))) - (topic (erc-trim-string (erc-response.contents parsed))) - (time (format-time-string erc-server-timestamp-format))) - (pcase-let ((`(,nick ,login ,host) - (erc-parse-user (erc-response.sender parsed)))) - (erc-update-channel-member ch nick nick nil nil nil nil nil nil host login) - (erc-update-channel-topic ch (format "%s\C-o (%s, %s)" topic nick time)) - (erc-display-message parsed 'notice (erc-get-buffer ch proc) - 'TOPIC ?n nick ?u login ?h host - ?c ch ?T topic)))) - -(define-erc-response-handler (WALLOPS) - "Display a WALLOPS message." nil - (let ((message (erc-response.contents parsed))) - (pcase-let ((`(,nick ,_login ,_host) - (erc-parse-user (erc-response.sender parsed)))) - (erc-display-message - parsed 'notice nil - 'WALLOPS ?n nick ?m message)))) - -(define-erc-response-handler (001) - "Set `erc-server-current-nick' to reflect server settings. -Then display the welcome message." - nil - (erc-set-current-nick (car (erc-response.command-args parsed))) - (erc-update-mode-line) ; needed here? - (setq erc-nick-change-attempt-count 0) - (setq erc-default-nicks (if (consp erc-nick) erc-nick (list erc-nick))) - (erc-display-message - parsed 'notice 'active (erc-response.contents parsed))) - -(define-erc-response-handler (MOTD 002 003 371 372 374 375) - "Display the server's message of the day." nil - (erc-handle-login) - (erc-display-message - parsed 'notice (if erc-server-connected 'active proc) - (erc-response.contents parsed))) - -(define-erc-response-handler (376 422) - "End of MOTD/MOTD is missing." nil - (erc-server-MOTD proc parsed) - (erc-connection-established proc parsed)) - -(define-erc-response-handler (004) - "Display the server's identification." nil - (pcase-let ((`(,server-name ,server-version) - (cdr (erc-response.command-args parsed)))) - (setq erc-server-version server-version) - (setq erc-server-announced-name server-name) - (erc-update-mode-line-buffer (process-buffer proc)) - (erc-display-message - parsed 'notice proc - 's004 ?s server-name ?v server-version - ?U (nth 3 (erc-response.command-args parsed)) - ?C (nth 4 (erc-response.command-args parsed))))) - -(defun erc--parse-isupport-value (value) - "Return list of unescaped components from an \"ISUPPORT\" VALUE." - ;; https://tools.ietf.org/html/draft-brocklesby-irc-isupport-03#section-2 - ;; - ;; > The server SHOULD send "X", not "X="; this is the normalized form. - ;; - (let (case-fold-search) - (mapcar - (lambda (v) - (let ((start 0) - m - c) - (while (and (< start (length v)) - (string-match "[\\]x[0-9A-F][0-9A-F]" v start)) - (setq m (substring v (+ 2 (match-beginning 0)) (match-end 0)) - c (string-to-number m 16)) - ;; In practice, this range is too liberal. The only - ;; escapes we're likely to see are ?\\, ?=, and ?\s. - (if (<= ?\s c ?~) - (setq v (concat (substring v 0 (match-beginning 0)) - (string c) - (substring v (match-end 0))) - start (- (match-end 0) 3)) - (setq start (match-end 0)))) - v)) - (if (string-search "," value) - (split-string value ",") - (list value))))) - -(defun erc--get-isupport-entry (key &optional single) - "Return an item for \"ISUPPORT\" token KEY, a symbol. -When a lookup fails return nil. Otherwise return a list whose -CAR is KEY and whose CDR is zero or more strings. With SINGLE, -just return the first value, if any. The latter is potentially -ambiguous and only useful for tokens supporting a single -primitive value." - (if-let* ((table (or erc--isupport-params - (erc-with-server-buffer erc--isupport-params))) - (value (with-memoization (gethash key table) - (when-let ((v (assoc (symbol-name key) - (or erc-server-parameters - (erc-with-server-buffer - erc-server-parameters))))) - (if-let ((val (cdr v)) - ((not (string-empty-p val)))) - (erc--parse-isupport-value val) - '--empty--))))) - (pcase value - ('--empty-- (unless single (list key))) - (`(,head . ,_) (if single head (cons key value)))) - (when table - (remhash key table)))) - -;; While it's better to depend on interfaces than specific types, -;; using `cl-struct-slot-value' or similar to extract a known slot at -;; runtime would incur a small "ducktyping" tax, which should probably -;; be avoided when running hundreds of times per incoming message. -;; Instead of separate keys per data type, we could increment a -;; counter whenever a new 005 arrives. -(defmacro erc--with-isupport-data (param var &rest body) - "Return structured data stored in VAR for \"ISUPPORT\" PARAM. -Expect VAR's value to be an instance of `erc--isupport-data'. If -VAR is uninitialized or stale, evaluate BODY and assign the -result to VAR." - (declare (indent defun)) - `(erc-with-server-buffer - (pcase-let (((,@(list '\` (list param '\, 'key))) - (erc--get-isupport-entry ',param))) - (or (and ,var (eq key (erc--isupport-data-key ,var)) ,var) - (setq ,var (progn ,@body)))))) - -(define-erc-response-handler (005) - "Set the variable `erc-server-parameters' and display the received message. - -According to RFC 2812, suggests alternate servers on the network. -Many servers, however, use this code to show which parameters they have set, -for example, the network identifier, maximum allowed topic length, whether -certain commands are accepted and more. See documentation for -`erc-server-parameters' for more information on the parameters sent. - -A server may send more than one 005 message." - nil - (unless erc--isupport-params - (setq erc--isupport-params (make-hash-table))) - (let* ((args (cdr (erc-response.command-args parsed))) - (line (string-join args " "))) - (while args - (let ((section (pop args)) - key - value - negated) - (when (string-match - (rx bot (| (: (group (+ (any "A-Z"))) "=" (group (* nonl))) - (: (? (group "-")) (group (+ (any "A-Z"))))) - eot) - section) - (setq key (or (match-string 1 section) (match-string 4 section)) - value (match-string 2 section) - negated (and (match-string 3 section) '-)) - (setf (alist-get key erc-server-parameters '- 'remove #'equal) - (or value negated)) - (remhash (intern key) erc--isupport-params)))) - (erc-display-message parsed 'notice proc line) - nil)) - -(define-erc-response-handler (221) - "Display the current user modes." nil - (let* ((nick (car (erc-response.command-args parsed))) - (modes (mapconcat #'identity - (cdr (erc-response.command-args parsed)) " "))) - (erc--update-modes (cdr (erc-response.command-args parsed))) - (erc-display-message parsed 'notice 'active 's221 ?n nick ?m modes))) - -(define-erc-response-handler (252) - "Display the number of IRC operators online." nil - (erc-display-message parsed 'notice 'active 's252 - ?i (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (253) - "Display the number of unknown connections." nil - (erc-display-message parsed 'notice 'active 's253 - ?i (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (254) - "Display the number of channels formed." nil - (erc-display-message parsed 'notice 'active 's254 - ?i (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (250 251 255 256 257 258 259 265 266 377 378) - "Generic display of server messages as notices. - -See `erc-display-server-message'." nil - (erc-display-server-message proc parsed)) - -(define-erc-response-handler (263) "RPL_TRYAGAIN." nil - (erc-handle-unknown-server-response proc parsed)) - -(define-erc-response-handler (275) - "Display secure connection message." nil - (pcase-let ((`(,nick ,_user ,_message) - (cdr (erc-response.command-args parsed)))) - (erc-display-message - parsed 'notice 'active 's275 - ?n nick - ?m (mapconcat #'identity (cddr (erc-response.command-args parsed)) - " ")))) - -(define-erc-response-handler (290) - "Handle dancer-ircd CAPAB messages." nil nil) - -(define-erc-response-handler (301) - "AWAY notice." nil - (erc-display-message parsed 'notice 'active 's301 - ?n (cadr (erc-response.command-args parsed)) - ?r (erc-response.contents parsed))) - -(define-erc-response-handler (303) - "ISON reply" nil - (erc-display-message parsed 'notice 'active 's303 - ?n (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (305) - "Return from AWAYness." nil - (erc-process-away proc nil) - (erc-display-message parsed 'notice 'active - 's305 ?m (erc-response.contents parsed))) - -(define-erc-response-handler (306) - "Set AWAYness." nil - (erc-process-away proc t) - (erc-display-message parsed 'notice 'active - 's306 ?m (erc-response.contents parsed))) - -(define-erc-response-handler (307) - "Display nick-identified message." nil - (pcase-let ((`(,nick ,_user ,_message) - (cdr (erc-response.command-args parsed)))) - (erc-display-message - parsed 'notice 'active 's307 - ?n nick - ?m (mapconcat #'identity (cddr (erc-response.command-args parsed)) - " ")))) - -(define-erc-response-handler (311 314) - "WHOIS/WHOWAS notices." nil - (let ((fname (erc-response.contents parsed)) - (catalog-entry (intern (format "s%s" (erc-response.command parsed))))) - (pcase-let ((`(,nick ,user ,host) - (cdr (erc-response.command-args parsed)))) - (erc-update-user-nick nick nick host user fname) - (erc-display-message - parsed 'notice 'active catalog-entry - ?n nick ?f fname ?u user ?h host)))) - -(define-erc-response-handler (312) - "Server name response in WHOIS." nil - (pcase-let ((`(,nick ,server-host) - (cdr (erc-response.command-args parsed)))) - (erc-display-message - parsed 'notice 'active 's312 - ?n nick ?s server-host ?c (erc-response.contents parsed)))) - -(define-erc-response-handler (313) - "IRC Operator response in WHOIS." nil - (erc-display-message - parsed 'notice 'active 's313 - ?n (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (315 318 323 369) - ;; 315 - End of WHO - ;; 318 - End of WHOIS list - ;; 323 - End of channel LIST - ;; 369 - End of WHOWAS - "End of WHO/WHOIS/LIST/WHOWAS notices." nil - (ignore proc parsed)) - -(define-erc-response-handler (317) - "IDLE notice." nil - (pcase-let ((`(,nick ,seconds-idle ,on-since ,time) - (cdr (erc-response.command-args parsed)))) - (setq time (when on-since - (format-time-string erc-server-timestamp-format - (string-to-number on-since)))) - (erc-update-user-nick nick nick nil nil nil - (and time (format "on since %s" time))) - (if time - (erc-display-message - parsed 'notice 'active 's317-on-since - ?n nick ?i (erc-sec-to-time (string-to-number seconds-idle)) ?t time) - (erc-display-message - parsed 'notice 'active 's317 - ?n nick ?i (erc-sec-to-time (string-to-number seconds-idle)))))) - -(define-erc-response-handler (319) - "Channel names in WHOIS response." nil - (erc-display-message - parsed 'notice 'active 's319 - ?n (cadr (erc-response.command-args parsed)) - ?c (erc-response.contents parsed))) - -(define-erc-response-handler (320) - "Identified user in WHOIS." nil - (erc-display-message - parsed 'notice 'active 's320 - ?n (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (321) - "LIST header." nil - (setq erc-channel-list nil)) - -(defun erc-server-321-message (proc parsed) - "Display a message for the 321 event." - (erc-display-message parsed 'notice proc 's321) - nil) -(add-hook 'erc-server-321-functions #'erc-server-321-message t) - -(define-erc-response-handler (322) - "LIST notice." nil - (let ((topic (erc-response.contents parsed))) - (pcase-let ((`(,channel ,_num-users) - (cdr (erc-response.command-args parsed)))) - (add-to-list 'erc-channel-list (list channel)) - (erc-update-channel-topic channel topic)))) - -(defun erc-server-322-message (proc parsed) - "Display a message for the 322 event." - (let ((topic (erc-response.contents parsed))) - (pcase-let ((`(,channel ,num-users) - (cdr (erc-response.command-args parsed)))) - (erc-display-message - parsed 'notice proc 's322 - ?c channel ?u num-users ?t (or topic ""))))) -(add-hook 'erc-server-322-functions #'erc-server-322-message t) - -(define-erc-response-handler (324) - "Channel or nick modes." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (modes (mapconcat #'identity (cddr (erc-response.command-args parsed)) - " "))) - (erc--init-channel-modes channel (cddr (erc-response.command-args parsed))) - (erc-display-message - parsed 'notice (erc-get-buffer channel proc) - 's324 ?c channel ?m modes))) - -(define-erc-response-handler (328) - "Channel URL." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (url (erc-response.contents parsed))) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - 's328 ?c channel ?u url))) - -(define-erc-response-handler (329) - "Channel creation date." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (time (string-to-number - (nth 2 (erc-response.command-args parsed))))) - (erc-display-message - parsed 'notice (erc-get-buffer channel proc) - 's329 ?c channel ?t (format-time-string erc-server-timestamp-format - time)))) - -(define-erc-response-handler (330) - "Nick is authed as (on Quakenet network)." nil - ;; FIXME: I don't know what the magic numbers mean. Mummy, make - ;; the magic numbers go away. - ;; No seriously, I have no clue about the format of this command, - ;; and don't sit on Quakenet, so can't test. Originally we had: - ;; nick == (aref parsed 3) - ;; authaccount == (aref parsed 4) - ;; authmsg == (aref parsed 5) - ;; The guesses below are, well, just that. -- Lawrence 2004/05/10 - (let ((nick (cadr (erc-response.command-args parsed))) - (authaccount (nth 2 (erc-response.command-args parsed))) - (authmsg (erc-response.contents parsed))) - (erc-display-message parsed 'notice 'active 's330 - ?n nick ?a authmsg ?i authaccount))) - -(define-erc-response-handler (331) - "No topic set for channel." nil - (let ((channel (cadr (erc-response.command-args parsed)))) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - 's331 ?c channel))) - -(define-erc-response-handler (332) - "TOPIC notice." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (topic (erc-response.contents parsed))) - (erc-update-channel-topic channel topic) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - 's332 ?c channel ?T topic))) - -(define-erc-response-handler (333) - "Who set the topic, and when." nil - (pcase-let ((`(,channel ,nick ,time) - (cdr (erc-response.command-args parsed)))) - (setq time (format-time-string erc-server-timestamp-format - (string-to-number time))) - (erc-update-channel-topic channel - (format "\C-o (%s, %s)" nick time) - 'append) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - 's333 ?c channel ?n nick ?t time))) - -(define-erc-response-handler (341) - "Let user know when an INVITE attempt has been sent successfully." - nil - (pcase-let ((`(,nick ,channel) - (cdr (erc-response.command-args parsed)))) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - 's341 ?n nick ?c channel))) - -(defun erc--extract-352-full-name (contents) - "Return full name from 352 trailing param, discarding hop count." - (pcase contents - ((rx (: bot (+ (any "0-9")) " ") (let full-name (group (* nonl))) eot) - full-name) - (_ contents))) - -(define-erc-response-handler (352) - "RPL_WHOREPLY response." nil - (pcase-let* - ((`(,_ ,channel ,user ,host ,_server ,nick ,flags, hop-real) - (erc-response.command-args parsed)) - (full-name (erc--extract-352-full-name hop-real)) - (selfp (string= channel "*")) - (template (if selfp 's352-you 's352))) - (if selfp - (erc-update-user-nick nick nick host user full-name) - (erc-update-channel-member channel nick nick nil nil nil nil nil nil - host user full-name)) - (erc-display-message parsed 'notice 'active template - ?c channel ?n nick ?a flags - ?u user ?h host ?f full-name))) - -(define-erc-response-handler (353) - "NAMES notice." nil - (let ((channel (nth 2 (erc-response.command-args parsed))) - (users (erc-response.contents parsed))) - (erc-display-message parsed 'notice (or (erc-get-buffer channel proc) - 'active) - 's353 ?c channel ?u users) - (erc-with-buffer (channel proc) - (erc-channel-receive-names users)))) - -(define-erc-response-handler (366) - "End of NAMES." nil - (erc-with-buffer ((cadr (erc-response.command-args parsed)) proc) - (erc-channel-end-receiving-names)) - (erc--ensure-query-members) - nil) - -(define-erc-response-handler (367) - "Channel ban list entries." nil - (pcase-let ((`(,channel ,banmask ,setter ,time) - (cdr (erc-response.command-args parsed)))) - ;; setter and time are not standard - (if setter - (erc-display-message parsed 'notice 'active 's367-set-by - ?c channel - ?b banmask - ?s setter - ?t (or time "")) - (erc-display-message parsed 'notice 'active 's367 - ?c channel - ?b banmask)))) - -(define-erc-response-handler (368) - "End of channel ban list." nil - (let ((channel (cadr (erc-response.command-args parsed)))) - (erc-display-message parsed 'notice 'active 's368 - ?c channel))) - -(define-erc-response-handler (379) - "Forwarding to another channel." nil - ;; FIXME: Yet more magic numbers in original code, I'm guessing this - ;; command takes two arguments, and doesn't have any "contents". -- - ;; Lawrence 2004/05/10 - (pcase-let ((`(,from ,to) - (cdr (erc-response.command-args parsed)))) - (erc-display-message parsed 'notice 'active - 's379 ?c from ?f to))) - -(define-erc-response-handler (391) - "Server's time string." nil - (erc-display-message - parsed 'notice 'active - 's391 ?s (cadr (erc-response.command-args parsed)) - ?t (nth 2 (erc-response.command-args parsed)))) - -;; https://defs.ircdocs.horse/defs/numerics.html#rpl-visiblehost-396 -;; As of ERC 5.6, if the client hasn't yet joined any channels, -;; there's a good chance a server user for the current nick simply -;; doesn't exist (and there's not enough info in this reply to create -;; one). To fix this, ERC could WHO itself on 372 or similar if it -;; hasn't yet received a 900. -(define-erc-response-handler (396) - "RPL_VISIBLEHOST or RPL_YOURDISPLAYHOST or RPL_HOSTHIDDEN." nil - (pcase-let* ((userhost (cadr (erc-response.command-args parsed))) - ;; Behavior blindly copied from event_hosthidden in irssi 1.4. - (rejectrx (rx (| (: bot (in ?@ ?: ?-)) (in ?* ?? ?! ?# ?& ?\s) - (: ?- eot)))) - (`(,_ ,user ,host) (and (not (string-match rejectrx userhost)) - (erc--parse-nuh userhost)))) - (when host - (erc-update-user-nick (erc-current-nick) nil host user) - (erc-display-message parsed 'notice 'active 's396 ?s userhost)))) - -(define-erc-response-handler (401) - "No such nick/channel." nil - (let ((nick/channel (cadr (erc-response.command-args parsed)))) - (defvar erc-whowas-on-nosuchnick) - (when erc-whowas-on-nosuchnick - (erc-log (format "cmd: WHOWAS: %s" nick/channel)) - (erc-server-send (format "WHOWAS %s 1" nick/channel))) - (erc-display-message parsed '(notice error) 'active - 's401 ?n nick/channel) - (unless (erc-channel-p nick/channel) - (erc-remove-user nick/channel)))) - -(define-erc-response-handler (402) - "No such server." nil - (erc-display-message parsed '(notice error) 'active - 's402 ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (403) - "No such channel." nil - (erc-display-message parsed '(notice error) 'active - 's403 ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (404) - "Cannot send to channel." nil - (erc-display-message parsed '(notice error) 'active - 's404 ?c (cadr (erc-response.command-args parsed)))) - - -(define-erc-response-handler (405) - "Can't join that many channels." nil - (erc-display-message parsed '(notice error) 'active - 's405 ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (406) - "No such nick." nil - (erc-display-message parsed '(notice error) 'active - 's406 ?n (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (412) - "No text to send." nil - (erc-display-message parsed '(notice error) 'active 's412)) - -(define-erc-response-handler (421) - "Unknown command." nil - (erc-display-message parsed '(notice error) 'active 's421 - ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (432) - "Bad nick." nil - (erc-display-message parsed '(notice error) 'active 's432 - ?n (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (433) - "Login-time \"nick in use\"." nil - (when erc-server-connected - (erc-networks--id-reload erc-networks--id proc parsed)) - (erc-nickname-in-use (cadr (erc-response.command-args parsed)) - "already in use")) - -(define-erc-response-handler (437) - "Nick temporarily unavailable (on IRCnet)." nil - (let ((nick/channel (cadr (erc-response.command-args parsed)))) - (unless (erc-channel-p nick/channel) - (erc-nickname-in-use nick/channel "temporarily unavailable")))) - -(define-erc-response-handler (442) - "Not on channel." nil - (erc-display-message parsed '(notice error) 'active 's442 - ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (461) - "Not enough parameters for command." nil - (erc-display-message parsed '(notice error) 'active 's461 - ?c (cadr (erc-response.command-args parsed)) - ?m (erc-response.contents parsed))) - -(define-erc-response-handler (465) - "You are banned from this server." nil - (setq erc-server-banned t) - ;; show the server's message, as a reason might be provided - (erc-display-error-notice - parsed - (erc-response.contents parsed))) - -(define-erc-response-handler (471) - "ERR_CHANNELISFULL: channel full." nil - (erc-display-message parsed '(notice error) nil 's471 - ?c (cadr (erc-response.command-args parsed)) - ?s (erc-response.contents parsed))) - -(define-erc-response-handler (473) - "ERR_INVITEONLYCHAN: channel invitation only." nil - (erc-display-message parsed '(notice error) nil 's473 - ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (474) - "Banned from channel errors." nil - (erc-display-message parsed '(notice error) nil - (intern (format "s%s" - (erc-response.command parsed))) - ?c (cadr (erc-response.command-args parsed)))) - -(define-erc-response-handler (475) - "Channel key needed." nil - (erc-display-message parsed '(notice error) nil 's475 - ?c (cadr (erc-response.command-args parsed))) - (defvar erc-prompt-for-channel-key) - (defvar erc--called-as-input-p) - (when erc-prompt-for-channel-key - (let ((channel (cadr (erc-response.command-args parsed))) - (erc--called-as-input-p t) - (key (read-from-minibuffer - (format "Channel %s is mode +k. Enter key (RET to cancel): " - (cadr (erc-response.command-args parsed)))))) - (when (and key (> (length key) 0)) - (erc-cmd-JOIN channel key))))) - -(define-erc-response-handler (477) - "Channel doesn't support modes." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (message (erc-response.contents parsed))) - (erc-display-message parsed 'notice (erc-get-buffer channel proc) - (format "%s: %s" channel message)))) - -(define-erc-response-handler (482) - "You need to be a channel operator to do that." nil - (let ((channel (cadr (erc-response.command-args parsed))) - (message (erc-response.contents parsed))) - (erc-display-message parsed '(notice error) 'active 's482 - ?c channel ?m message))) - -(define-erc-response-handler (671) - "Secure connection response in WHOIS." nil - (let ((nick (cadr (erc-response.command-args parsed))) - (securemsg (erc-response.contents parsed))) - (erc-display-message parsed 'notice 'active 's671 - ?n nick ?a securemsg))) - -(define-erc-response-handler (900) - "Handle a \"RPL_LOGGEDIN\" server command. -Some servers don't consider this SASL-specific but rather just an -indication of a server-side state change from logged-out to -logged-in." nil - ;; Whenever ERC starts caring about user accounts, it should record - ;; the session as being logged here. - (erc-display-message parsed 'notice proc (erc-response.contents parsed))) - -(define-erc-response-handler (431 445 446 451 462 463 464 481 483 484 485 - 491 501 502) - ;; 431 - No nickname given - ;; 445 - SUMMON has been disabled - ;; 446 - USERS has been disabled - ;; 451 - You have not registered - ;; 462 - Unauthorized command (already registered) - ;; 463 - Your host isn't among the privileged - ;; 464 - Password incorrect - ;; 481 - Need IRCop privileges - ;; 483 - You can't kill a server! - ;; 484 - Your connection is restricted! - ;; 485 - You're not the original channel operator - ;; 491 - No O-lines for your host - ;; 501 - Unknown MODE flag - ;; 502 - Cannot change mode for other users - "Generic display of server error messages. - -See `erc-display-error-notice'." nil - (erc-display-error-notice - parsed - (intern (format "s%s" (erc-response.command parsed))))) - -;; FIXME: These are yet to be implemented, they're just stubs for now -;; -- Lawrence 2004/05/12 - -;; response numbers left here for reference - -;; (define-erc-response-handler (323 364 365 381 382 392 393 394 395 -;; 200 201 202 203 204 205 206 208 209 211 212 213 -;; 214 215 216 217 218 219 241 242 243 244 249 261 -;; 262 302 342 351 407 409 411 413 414 415 -;; 423 424 436 441 443 444 467 472 KILL) -;; nil nil -;; (ignore proc parsed)) - -(provide 'erc-backend) - -;;; erc-backend.el ends here diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el deleted file mode 100644 index 36263f6b893..00000000000 --- a/lisp/erc/erc-button.el +++ /dev/null @@ -1,885 +0,0 @@ -;;; erc-button.el --- A way of buttonizing certain things in ERC buffers -*- lexical-binding:t -*- - -;; Copyright (C) 1996-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, irc, button, url, regexp -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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 init file: -;; (require 'erc-button) -;; (erc-button-mode 1) -;; -;; Todo: -;; * Rewrite all this to do the same, but use button.el. 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) -(require 'browse-url) - -;;; 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 30) - (add-hook 'erc-send-modify-hook #'erc-button-add-buttons 30) - (add-hook 'erc-mode-hook #'erc-button-setup 91) - (unless erc--updating-modules-p (erc-buffer-do #'erc-button-setup)) - (add-hook 'erc--tab-functions #'erc-button-next) - (erc--modify-local-map t "" #'erc-button-previous)) - ((remove-hook 'erc-insert-modify-hook #'erc-button-add-buttons) - (remove-hook 'erc-send-modify-hook #'erc-button-add-buttons) - (remove-hook 'erc-mode-hook #'erc-button-setup) - (remove-hook 'erc--tab-functions #'erc-button-next) - (erc--modify-local-map nil "" #'erc-button-previous))) - -;;; Variables - -(defface erc-button '((t :weight bold)) - "ERC button face." - :group 'erc-faces) - -(defface erc-button-nick-default-face '((t :inherit erc-nick-default-face)) - "Default face for a buttonized nickname." - :package-version '(ERC . "5.6") - :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-button-nick-default-face - "Face used for ERC nickname buttons." - :package-version '(ERC . "5.6") - :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 browse-url-button-regexp - "Regular expression that matches URLs." - :version "27.1" - :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'." - :type '(choice integer boolean)) - -(defcustom erc-button-buttonize-nicks t - "Flag indicating whether nicks should be buttonized. -Note that beginning in ERC 5.6, some functionality provided by -other modules, such as `fill-wrap', may depend on this option -being non-nil." - :type 'boolean) - -(defcustom erc-button-rfc-url "https://tools.ietf.org/html/rfc%s" - "URL used to browse RFC references. -%s is replaced by the number." - :type 'string - :version "28.1") - -(define-obsolete-variable-alias 'erc-button-google-url - 'erc-button-search-url "27.1") - -(defcustom erc-button-search-url "https://duckduckgo.com/?q=%s" - "URL used to search for a term. -%s is replaced by the search string." - :version "28.1" - :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. - '((erc-button-url-regexp 0 t browse-url-button-open-url 0) - ;; (" ]+\\) *>" 0 t browse-url-button-open-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: ?\\|(info \\)[\"]\\(([^\"]+\\)[\"])?" 0 t info 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-search-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. Also, use of the special symbol `nicknames' - for this slot was deprecated in ERC 5.6, but users can still - use `erc-button-buttonize-nicks' to control whether nicks get - buttonized. And because customizing a corresponding CALLBACK - is no longer possible, an escape hatch has been provided via - the variable `erc-button-nickname-callback-function'. - -BUTTON is the number of the regexp grouping actually matching the - button. - -FORM is either a boolean or a special variable whose value must - be non-nil for the button to be added. It can also be a - function to call in place of `erc-button-add-button' with the - exact same arguments. When FORM is also a special variable, - ERC disregards the variable and calls the function. Note that - arbitrary s-expressions were deprecated in ERC 5.6 and may not - be respected in the future. If necessary, users can instead - supply a function that calls `erc-button-add-button' when such - an expression is non-nil. - -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." - :package-version '(ERC . "5.6") - :type '(repeat - (list :tag "Button" - (choice :tag "Matches" - regexp - (variable :tag "Variable containing regexp") - (repeat :tag "List of words" string) - (alist :key-type string :value-type sexp)) - (integer :tag "Number of the regexp section that matches") - (choice :tag "When to buttonize" - (const :tag "Always" t) - (function :tag "Alternative buttonizing function") - (variable :tag "Var with value treated as boolean")) - (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 "https://www.emacswiki.org/emacs/" - "URL of the EmacsWiki website." - :type 'string - :version "28.1") - -(defcustom erc-emacswiki-lisp-url "https://www.emacswiki.org/elisp/" - "URL of the EmacsWiki ELisp area." - :type 'string) - -(defvar erc-button-highlight-nick-once '(QUIT PART JOIN) - "Messages for which to buttonize only the first nick occurrence.") - -(defvar erc-button-keymap - (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") #'erc-button-press-button) - (define-key map (kbd "") #'erc-button-click-button) - (define-key map (kbd "TAB") #'erc-button-next) - (define-key map (kbd "") #'erc-button-previous) - (define-key map [follow-link] 'mouse-face) - (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) - table) - "Syntax table used when buttonizing messages. -This syntax table should make all the valid nick characters word -constituents.") - -(defvar erc-button-keys-added nil - "Internal variable used to keep track of whether we've added the -global-level ERC button keys yet.") -(make-obsolete-variable 'erc-button-keys-added "no longer relevant" "30.1") - -(defvar-local erc-button--has-nickname-entry nil - "Whether `erc-button-alist' contains a legacy `nicknames' entry.") - -(defun erc-button-setup () - "Perform major-mode setup for ERC's button module. -Note that prior to ERC 5.6, this function used to modify -`erc-mode-map', but that's now handled by the mode toggles -themselves." - (setq erc-button-keys-added t) - (cl-assert (derived-mode-p 'erc-mode)) - ;; It would probably suffice to run this in server buffers alone, - ;; even though buttonizing happens in all ERC buffers and users have - ;; been known to set `erc-button-alist' locally. - (dolist (entry erc-button-alist) - (pcase entry - ((or `(nicknames ,_ ,sym . ,_) `('nicknames ,_ ,sym . ,_)) - (setq erc-button--has-nickname-entry t) - (unless (eq sym 'erc-button-buttonize-nicks) - (erc--warn-once-before-connect 'erc-button-mode - "The legacy `nicknames' entry in `erc-button-alist'" - " is deprecated. See doc string for details."))) - ((and `(,_ ,_ ,form . ,_) - (guard (not (or (and (symbolp form) - (special-variable-p form)) - (functionp form))))) - (erc--warn-once-before-connect 'erc-button-mode - "Arbitrary sexps for the third, FORM slot of `erc-button-alist'" - " entries are deprecated. Either use a variable or a function" - " that conditionally calls `erc-button-add-button'."))))) - -(defvar erc-button-nickname-callback-function #'erc-button--perform-nick-popup - "Escape hatch for users needing a non-standard nick-button callback. -Value should be a function accepting a NICK and any number of -trailing arguments that are as yet unspecified. Runs when -clicking \\`' or hitting \\`RET' atop a nickname button.") -(make-obsolete-variable 'erc-button-nickname-callback-function - "default provides essential functionality" "30.1") - -(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-field-text-motion t) - (alist erc-button-alist) - regexp) - (erc-button-remove-old-buttons) - (unless (or erc-button--has-nickname-entry - (not erc-button-buttonize-nicks) - (and (erc--memq-msg-prop 'erc--skip 'button) - (not (setq alist nil)))) - (erc-button-add-nickname-buttons - `(_ _ erc-button--modify-nick-function - ,erc-button-nickname-callback-function))) - (dolist (entry alist) - (if (or (eq (car entry) 'nicknames) - ;; Old form retained for backward compatibility. - (equal (car entry) (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--extract-form (form) - ;; If a special-variable is also a function, favor the function. - (cond ((eq t form) t) - ((functionp form) form) - ((and (symbolp form) (special-variable-p form)) - (while (let ((val (symbol-value form))) - (prog1 (and (not (eq val form)) - (symbolp val) - (special-variable-p val)) - (setq form val)))) - form) - (t (eval form t)))) - -(cl-defstruct erc-button--nick - ( bounds nil :type cons - ;; Indicates the nick's position in the current message. BEG is - ;; normally also point. - :documentation "A cons of (BEG . END).") - ( data nil :type (or null cons) - ;; When non-nil, the CAR must be a non-casemapped nickname. For - ;; compatibility, the CDR should probably be nil, but this may - ;; have to change eventually. If non-nil, the entire cons should - ;; be mutated rather than replaced because it's used as a key in - ;; hash tables and text-property searches. - :documentation "A unique cons whose car is a nickname.") - ( downcased nil :type (or null string) - :documentation "The case-mapped nickname sans text properties.") - ( user nil :type (or null erc-server-user) - ;; Not necessarily present in `erc-server-users'. - :documentation "A possibly nil or spoofed `erc-server-user'.") - ( cusr nil :type (or null erc-channel-user) - ;; The CDR of a value from an `erc-channel-members' table. - :documentation "A possibly nil `erc-channel-user'.") - ( nickname-face erc-button-nickname-face :type symbol - :documentation "Temp `erc-button-nickname-face' while buttonizing.") - ( mouse-face erc-button-mouse-face :type symbol - :documentation "Function to return possibly cached face.") - ( face-cache nil :type (or null function))) - -;; This variable is intended to serve as a "core" to be wrapped by -;; (built-in) modules during setup. It's unclear whether -;; `add-function's practice of removing existing advice before -;; re-adding it is desirable when integrating modules since we're -;; mostly concerned with ensuring one "piece" precedes or follows -;; another (specific piece), which may not yet (or ever) be present. - -(defvar erc-button--modify-nick-function #'identity - "Function to possibly modify aspects of nick being buttonized. -Called with one argument, an `erc-button--nick' object, or nil. -The function should return the same (or similar) object when -buttonizing ought to proceed and nil otherwise. While running, -all faces defined in `erc-button' are bound temporarily and can -be updated at will.") - -(defvar-local erc-button--phantom-cmems nil) - -(defvar erc-button--fallback-cmem-function - #'erc-button--get-user-from-spkr-prop - "Function to determine channel member if not found in the usual places. -Called with DOWNCASED-NICK, NICK, NICK-BOUNDS, and COUNT when -`erc-button-add-nickname-buttons' cannot find a user object for -DOWNCASED-NICK in `erc-channel-members' or `erc-server-users'. -NICK-BOUNDS is a cons of buffer positions, and COUNT is a number -incremented with each visit, starting at 1.") - -(defun erc-button--get-user-from-spkr-prop (_ _ _ count) - "Attempt to obtain an `erc-channel-user' from current \"msg props\". -But only do so when COUNT is 1, meaning this is the first button -candidate in the just-inserted message." - (and-let* (((= 1 count)) - (nick (erc--check-msg-prop 'erc--spkr))) - (gethash nick erc-channel-members))) - -;; Historical or fictitious users. As long as these two structs -;; remain superficial "subclasses" with the same slots and defaults, -;; they can live here instead of in erc-common.el. -(cl-defstruct (erc--phantom-channel-user (:include erc-channel-user))) -(cl-defstruct (erc--phantom-server-user (:include erc-server-user))) - -(defun erc-button--add-phantom-speaker (downcased nuh _parsed) - (pcase-let* ((`(,nick ,login ,host) nuh) - (cmem (gethash downcased erc-button--phantom-cmems)) - (user (or (car cmem) - (make-erc--phantom-server-user - :nickname nick - :host (and (not (string-empty-p host)) host) - :login (and (not (string-empty-p login)) login)))) - (cuser (or (cdr cmem) - (make-erc--phantom-channel-user - :last-message-time (current-time))))) - (puthash downcased (cons user cuser) erc-button--phantom-cmems) - (cons user cuser))) - -(defun erc-button--get-phantom-cmem (down _word _bounds _count) - (gethash down erc-button--phantom-cmems)) - -(define-minor-mode erc-button--phantom-users-mode - "Minor mode to recognize unknown speakers. -Expect to be used by module setup code for creating placeholder -users on the fly during history playback. Treat an unknown -\"PRIVMSG\" speaker, like \"\", as if they previously -appeared in a prior \"353\" message and are thus a known member -of the channel. However, don't bother creating an actual -`erc-channel-user' object because their status prefix is unknown. -Instead, just spoof an `erc-server-user' and stash it during -\"PRIVMSG\" handling via `erc--cmem-from-nick-function' and -retrieve it during buttonizing via -`erc-button--fallback-cmem-function'." - :interactive nil - (if erc-button--phantom-users-mode - (progn - (add-function :after-until (local 'erc--cmem-from-nick-function) - #'erc-button--add-phantom-speaker '((depth . 30))) - (add-function :after-until (local 'erc-button--fallback-cmem-function) - #'erc-button--get-phantom-cmem '((depth . 50))) - (setq erc-button--phantom-cmems (make-hash-table :test #'equal))) - (remove-function (local 'erc--cmem-from-nick-function) - #'erc-button--add-phantom-speaker) - (remove-function (local 'erc-button--fallback-cmem-function) - #'erc-button--get-phantom-cmem) - (kill-local-variable 'erc-button--phantom-cmems))) - -(defun erc-button-add-nickname-buttons (entry) - "Search through the buffer for nicknames, and add buttons." - (when-let ((form (nth 2 entry)) - ;; Spoof `form' slot of default legacy `nicknames' entry - ;; so `erc-button--extract-form' sees a function value. - (form (let ((erc-button-buttonize-nicks - (and erc-button-buttonize-nicks - erc-button--modify-nick-function))) - (erc-button--extract-form form))) - (oncep (if-let ((erc-button-highlight-nick-once) - (c (erc--check-msg-prop 'erc--cmd)) - ((memq c erc-button-highlight-nick-once))) - 1 0)) - (seen 0)) - (goto-char (point-min)) - (while-let - (((or (zerop seen) (zerop oncep))) - ((erc-forward-word)) - (bounds (or (and (= 1 (cl-incf seen)) (erc--get-speaker-bounds)) - (erc-bounds-of-word-at-point))) - (word (buffer-substring-no-properties (car bounds) (cdr bounds))) - (down (erc-downcase word))) - (let* ((nick-obj t) - (cmem (and erc-channel-members - (or (gethash down erc-channel-members) - (funcall erc-button--fallback-cmem-function - down word bounds seen)))) - (user (or (and cmem (car cmem)) - (and erc-server-users (gethash down erc-server-users)))) - (data (list word))) - (when (or (not (functionp form)) - (and user - (setq nick-obj (funcall form (make-erc-button--nick - :bounds bounds :data data - :downcased down :user user - :cusr (cdr cmem))) - data (erc-button--nick-data nick-obj) - bounds (erc-button--nick-bounds nick-obj)))) - (erc-button-add-button (car bounds) (cdr bounds) (nth 3 entry) - nick-obj data)))))) - -(defun erc-button-add-buttons-1 (regexp entry) - "Search through the buffer for matches to ENTRY and add buttons." - (goto-char (point-min)) - (let (buttonizer) - (while - (and (re-search-forward regexp nil t) - (or buttonizer - (setq buttonizer - (and-let* - ((raw-form (nth 2 entry)) - (res (or (eq t raw-form) - (erc-button--extract-form raw-form)))) - (if (functionp res) res #'erc-button-add-button))))) - (let ((start (match-beginning (nth 1 entry))) - (end (match-end (nth 1 entry))) - (fun (nth 3 entry)) - (data (mapcar #'match-string-no-properties (nthcdr 4 entry)))) - (funcall buttonizer 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)) - (erc--restore-important-text-props '(mouse-face))) - -(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 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 " (- 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--merge-prop from to 'font-lock-face - (if (erc-button--nick-p nick-p) - (erc-button--nick-nickname-face nick-p) - erc-button-nickname-face) - nil (and (erc-button--nick-p nick-p) - (erc-button--nick-face-cache nick-p)))) - (when erc-button-face - (erc--merge-prop from to 'font-lock-face erc-button-face))) - (add-text-properties - from to - (nconc (and-let* ((face (or (and (erc-button--nick-p nick-p) - (erc-button--nick-mouse-face nick-p)) - erc-button-mouse-face))) - (list 'mouse-face face)) - (list 'erc-callback fun) - (list 'keymap erc-button-keymap) - (list 'rear-nonsticky t) - (and data (list 'erc-data data))))) - -(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 'font-lock-face))) - (pos from) - (end (next-single-property-change from 'font-lock-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 'font-lock-face new) - (setq pos end - old (erc-list (get-text-property pos 'font-lock-face)) - end (next-single-property-change pos 'font-lock-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))) - -(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." - (declare (advertised-calling-convention () "28.1")) - (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-function () - "Pseudo completion function that actually jumps to the next button. -For use on `completion-at-point-functions'." - (declare (obsolete erc-nickserv-identify "30.1")) - ;; FIXME: This is an abuse of completion-at-point-functions. - (when (< (point) (erc-beg-of-input-line)) - (let ((start (point))) - (lambda () - (let ((here start)) - ;; FIXME: Use next-single-property-change. - (while (and (get-text-property here 'erc-callback) - (not (= here (point-max)))) - (setq here (1+ here))) - (while (not (or (get-text-property here 'erc-callback) - (= here (point-max)))) - (setq here (1+ here))) - (if (< here (point-max)) - (goto-char here) - (error "No next button")) - t))))) - -(defvar erc-button--prev-next-predicate-functions - '(erc-button--end-of-button-p) - "Abnormal hook whose members can return non-nil to continue searching. -Otherwise, if all members return nil, point will stay at the -current button. Called with a single arg, a buffer position -greater than `point-min' with a text property of `erc-callback'.") - -(defun erc-button--end-of-button-p (point) - (get-text-property (1- point) 'erc-callback)) - -(defun erc--button-next (arg) - (let* ((nextp (prog1 (>= arg 1) (setq arg (max 1 (abs arg))))) - (search-fn (if nextp - #'next-single-char-property-change - #'previous-single-char-property-change)) - (start (point)) - (p start)) - (while (progn - ;; Break out of current search context. - (when-let ((low (max (point-min) (1- (pos-bol)))) - (high (min (point-max) (1+ (pos-eol)))) - (prop (get-text-property p 'erc-callback)) - (q (if nextp - (text-property-not-all p high - 'erc-callback prop) - (funcall search-fn p 'erc-callback nil low))) - ((< low q high))) - (setq p q)) - ;; Assume that buttons occur frequently enough that - ;; omitting LIMIT is acceptable. - (while - (and (setq p (funcall search-fn p 'erc-callback)) - (if nextp (< p erc-insert-marker) (/= p (point-min))) - (run-hook-with-args-until-success - 'erc-button--prev-next-predicate-functions p))) - (and arg - (< (point-min) p erc-insert-marker) - (goto-char p) - (not (zerop (cl-decf arg)))))) - (when (= (point) start) - (user-error (if nextp "No next button" "No previous button"))) - t)) - -(defun erc-button-next (&optional arg) - "Go to the ARGth next button." - (declare (advertised-calling-convention (arg) "30.1")) - (interactive "p") - (erc--button-next (or arg 1))) - -(defun erc-button-previous (&optional arg) - "Go to ARGth previous button." - (declare (advertised-calling-convention (arg) "30.1")) - (interactive "p") - (erc--button-next (- (or arg 1)))) - -(defun erc-button-previous-of-nick (arg) - "Go to ARGth previous button for nick at point." - (interactive "p") - (if-let* ((prop (get-text-property (point) 'erc-data)) - (erc-button--prev-next-predicate-functions - (cons (lambda (p) - (not (equal (get-text-property p 'erc-data) prop))) - erc-button--prev-next-predicate-functions))) - (erc--button-next (- arg)) - (user-error "No nick at point"))) - -(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) - ("Kick" . erc-button-cmd-KICK) - ("Msg" . erc-button-cmd-MSG) - ("Op" . erc-cmd-OP) - ("Query" . erc-cmd-QUERY) - ("Whois" . erc-cmd-WHOIS) - ("Lastlog" . erc-cmd-LASTLOG)) - "An alist of possible actions to take on a nickname. -For all entries (ACTION . FUNC), ERC offers ACTION as a possible -completion item and calls the selected entry's FUNC with the -buttonized nickname at point as the only argument. For -historical reasons, FUNC can also be an arbitrary sexp, in which -case, ERC binds the nick in question to the variable `nick' and -evaluates the expression. - -Examples: - (\"DebianDB\" . - (shell-command - (format - \"ldapsearch -x -P 2 -h db.debian.org -b dc=debian,dc=org ircnick=%s\" - nick)))" - :package-version '(ERC . "5.6") - :type '(repeat (cons (string :tag "Op") - (choice function sexp)))) - -(defun erc-button-cmd-KICK (nick) - "Prompt for a reason, then kick NICK via `erc-cmd-KICK'. -In server buffers, also prompt for a channel." - (erc-cmd-KICK - (or (and erc--target (erc-default-target)) - (let ((targets (mapcar (lambda (b) - (cons (erc--target-string - (buffer-local-value 'erc--target b)) - b)) - (erc-channel-list erc-server-process)))) - (completing-read (format "Channel (%s): " (caar targets)) - targets (pcase-lambda (`(,_ . ,buf)) - (with-current-buffer buf - (erc-get-channel-user nick))) - t nil t (caar targets)))) - nick - (read-string "Reason: "))) - -(defun erc-button-cmd-MSG (nick) - "Prompt for a message to NICK, and send it via `erc-cmd-MSG'." - (let ((msg (read-string (concat "Message to " nick ": ")))) - (erc-cmd-MSG (concat nick " " msg)))) - -(defvar-local erc-button--nick-popup-alist nil - "Internally controlled items for `erc-nick-popup-alist'.") - -(defun erc-nick-popup (nick) - (let* ((alist (append erc-nick-popup-alist erc-button--nick-popup-alist)) - (action (completing-read-case-insensitive - (format-message "What action to take on `%s'? " nick) alist)) - (code (cdr (assoc action alist)))) - (when code - (erc-set-active-buffer (current-buffer)) - (if (functionp code) - (funcall code nick) - (eval code `((nick . ,nick))))))) - -(defun erc-button--perform-nick-popup (nick &rest _) - "Call `erc-nick-popup' with NICK." - (erc-nick-popup nick)) - -;;; Callback functions -(defun erc-button-describe-symbol (symbol-name) - "Describe SYMBOL-NAME. -Use `describe-function' for functions, `describe-variable' for variables, -and `describe-symbol' 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 (describe-symbol 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 "@%s is %d:%02d local time" - beats hours minutes))) - -(defun erc-button--display-error-with-buttons - (from to fun nick-p &optional data regexp) - "Replace command in region with keys and return new bounds." - (let* ((o (buffer-substring from to)) - (s (substitute-command-keys o)) - (erc-button-face (and (equal o s) erc-button-face))) - (delete-region from to) - (insert s) - (erc-button-add-button from (point) fun nick-p data regexp))) - -;;;###autoload -(defun erc-button--display-error-notice-with-keys (maybe-buffer &rest strings) - "Add help keys to STRINGS for configuration-related admonishments. -Return inserted result. Expect MAYBE-BUFFER to be an ERC buffer, -a string, or nil. When it's a buffer, specify the `buffer' -argument when calling `erc-display-message'. Otherwise, add it -to STRINGS. If STRINGS contains any trailing non-nil -non-strings, concatenate leading string members before applying -`format'. Otherwise, just concatenate everything." - (let* ((buffer (if (bufferp maybe-buffer) - maybe-buffer - (when (stringp maybe-buffer) - (push maybe-buffer strings)) - 'active)) - (op (if (seq-every-p (lambda (o) (or (not o) (stringp o))) - (cdr strings)) - #'concat - (let ((head (pop strings))) - (while (or (stringp (car strings)) - (and strings (not (car strings)))) - (setq head (concat head (pop strings)))) - (push head strings)) - #'format)) - (string (apply op strings)) - ;; Avoid timestamps unless left-sided. - (skipp (or (bound-and-true-p erc-stamp--display-margin-mode) - (not (fboundp 'erc-timestamp-offset)) - (zerop (erc-timestamp-offset)))) - (erc--msg-prop-overrides `(,@(and skipp `((erc--skip stamp))) - ,@erc--msg-prop-overrides)) - (erc-insert-post-hook - (cons (lambda () - (setq string (buffer-substring (point-min) - (1- (point-max))))) - erc-insert-post-hook)) - (erc-button-alist - `((,(rx "\\[" (group (+ (not "]"))) "]") 0 - erc-button--display-error-with-buttons - erc-button-describe-symbol 1) - ,@erc-button-alist))) - (erc-display-message nil '(t notice error) buffer string) - string)) - -;;;###autoload -(defun erc-button--display-error-notice-with-keys-and-warn (&rest args) - "Like `erc-button--display-error-notice-with-keys' but also warn." - (let ((string (apply #'erc-button--display-error-notice-with-keys args))) - (with-temp-buffer - (insert string) - (goto-char (point-min)) - (with-syntax-table lisp-mode-syntax-table - (skip-syntax-forward "^-")) - (forward-char) - (erc--lwarn - 'erc :warning (buffer-substring-no-properties (point) (point-max)))))) - -(provide 'erc-button) - -;;; erc-button.el ends here -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-capab.el b/lisp/erc/erc-capab.el deleted file mode 100644 index cb3ce3cab89..00000000000 --- a/lisp/erc/erc-capab.el +++ /dev/null @@ -1,210 +0,0 @@ -;;; erc-capab.el --- support for dancer-ircd and hyperion's CAPAB -*- lexical-binding: t; -*- - -;; Copyright (C) 2006-2025 Free Software Foundation, Inc. - -;; Maintainer: Amin Bandali , F. Jason Park - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file defines the ERC module `erc-capab-identify', which allows -;; flagging of unidentified users on servers running dancer-ircd or -;; hyperion. freenode.net supports this capability, for example. - -;; With CAPAB IDENTIFY-MSG and IDENTIFY-CTCP enabled, messages from -;; users who have identified themselves to NickServ will have a plus -;; sign and messages from unidentified users will have a minus sign -;; added as a prefix. Note that it is not necessary for your nickname -;; to be identified in order to receive these marked messages. - -;; The plus or minus sign is removed from the message, and a prefix, -;; `erc-capab-identify-prefix', is inserted in the front of the user's -;; nickname if the nickname is not identified. - -;; Please note that once this has been enabled on a server, there is no -;; way to tell the server to stop sending marked messages. If you -;; disable this module, it will continue removing message flags, but the -;; unidentified nickname prefix will not be added to messages. - -;; Visit and -;; to find further -;; explanations of this capability. - -;; From freenode.net's web site (not there anymore) on how to mark -;; unidentified users: -;; "We recommend that you add an asterisk before the nick, and -;; optionally either highlight or colorize the line in some -;; appropriate fashion, if the user is not identified." - -;;; Usage: - -;; Put the following in your init file. - -;; (require 'erc-capab) -;; (erc-capab-identify-mode 1) - -;; `erc-capab-identify-prefix' will now be added to the beginning of -;; unidentified users' nicknames. The default is an asterisk, "*". -;; You can customize the prefix and the face used to display it, -;; `erc-capab-identify-unidentified'. If the value of -;; `erc-capab-identify-prefix' is nil or you disable this module (see -;; `erc-capab-identify-activated'), no prefix will be inserted, but the -;; flag sent by the server will still be stripped. - -;;; Code: - -(require 'erc) - -;;; Customization: - -(defgroup erc-capab nil - "Support for dancer-ircd's CAPAB settings." - :group 'erc) - -(defcustom erc-capab-identify-prefix "*" - "The prefix used for unidentified users. - -If you change this from the default \"*\", be sure to use a -character not found in IRC nicknames to avoid confusion." - :type '(choice string (const nil))) - -(defface erc-capab-identify-unidentified '((t)) ; same as `erc-default-face' - "Face to use for `erc-capab-identify-prefix'." - :group 'erc-faces) - -;;; Define module: - -;;;###autoload(autoload 'erc-capab-identify-mode "erc-capab" nil t) -(put 'capab-identify 'erc-group 'erc-capab) -(define-erc-module capab-identify nil - "Handle dancer-ircd's CAPAB IDENTIFY-MSG and IDENTIFY-CTCP." - ;; append so that `erc-server-parameters' is already set by `erc-server-005' - ((add-hook 'erc-server-005-functions #'erc-capab-identify-setup t) - (add-hook 'erc-server-290-functions #'erc-capab-identify-activate) - (add-hook 'erc-server-PRIVMSG-functions - #'erc-capab-identify-remove/set-identified-flag) - (add-hook 'erc-server-NOTICE-functions - #'erc-capab-identify-remove/set-identified-flag) - (add-hook 'erc-insert-modify-hook #'erc-capab-identify-add-prefix t) - (mapc (lambda (buffer) - (when buffer - (with-current-buffer buffer (erc-capab-identify-setup)))) - (erc-buffer-list #'erc-open-server-buffer-p))) - ((remove-hook 'erc-server-005-functions #'erc-capab-identify-setup) - (remove-hook 'erc-server-290-functions #'erc-capab-identify-activate) - ;; we don't remove the `erc-capab-identify-remove/set-identified-flag' hooks - ;; because there doesn't seem to be a way to tell the server to turn it off - (remove-hook 'erc-insert-modify-hook #'erc-capab-identify-add-prefix))) - -;;; Variables: - -(defvar-local erc-capab-identify-activated nil - "CAPAB IDENTIFY-MSG has been activated.") - -(defvar-local erc-capab-identify-sent nil - "CAPAB IDENTIFY-MSG and IDENTIFY-CTCP messages have been sent.") - -;;; Functions: - -(defun erc-capab-identify-setup (&optional _proc _parsed) - "Set up CAPAB IDENTIFY on the current server. - -Optional argument PROC is the current server's process. -Optional argument PARSED is the current message, a response struct. - -These arguments are sent to this function when called as a hook in -`erc-server-005-functions'." - (unless erc-capab-identify-sent - (erc-capab-identify-send-messages))) - -(defun erc-capab-identify-send-messages () - "Send CAPAB IDENTIFY messages if the server supports it." - (when (and (stringp erc-server-version) - (string-match "^\\(dancer-ircd\\|hyperion\\)" erc-server-version) - ;; could possibly check for '("IRCD" . "dancer") in - ;; `erc-server-parameters' instead of looking for a specific name - ;; in `erc-server-version' - (erc--get-isupport-entry 'CAPAB)) - (erc-log "Sending CAPAB IDENTIFY-MSG and IDENTIFY-CTCP") - (erc-server-send "CAPAB IDENTIFY-MSG") - (erc-server-send "CAPAB IDENTIFY-CTCP") - (setq erc-capab-identify-sent t))) - - -(defun erc-capab-identify-activate (_proc parsed) - "Set `erc-capab-identify-activated' and display an activation message. - -PROC is the current server's process. -PARSED is an `erc-parsed' response struct." - (when (member (erc-response.contents parsed) - '("IDENTIFY-MSG" "IDENTIFY-CTCP")) - (setq erc-capab-identify-activated t) - (erc-display-message - parsed 'notice 'active (format "%s activated" - (erc-response.contents parsed))))) - -(defun erc-capab-identify-remove/set-identified-flag (_proc parsed) - "Remove PARSED message's id flag and add the `erc-identified' text property. - -PROC is the current server's process. -PARSED is an `erc-parsed' response struct." - (let ((msg (erc-response.contents parsed))) - (when (and erc-capab-identify-activated - (string-match "^\\([-\\+]\\)\\(.+\\)$" msg)) - (setf (erc-response.contents parsed) - (if erc-capab-identify-mode - (propertize (match-string 2 msg) - 'erc-identified - (if (string= (match-string 1 msg) "+") - 1 - 0)) - (match-string 2 msg))) - nil))) - -(defun erc-capab-identify-add-prefix () - "Add `erc-capab-identify-prefix' to nickname if user is unidentified." - (when (and erc-capab-identify-prefix - (erc-with-server-buffer erc-capab-identify-activated)) - (goto-char (or (erc-find-parsed-property) (point-min))) - (let ((nickname (erc-capab-identify-get-unidentified-nickname - (erc-get-parsed-vector (point))))) - (when (and nickname - (goto-char (point-min)) - ;; assuming the first use of `nickname' is the sender's nick - (re-search-forward (regexp-quote nickname) nil t)) - (goto-char (match-beginning 0)) - (insert (propertize erc-capab-identify-prefix - 'font-lock-face - 'erc-capab-identify-unidentified)))))) - -(defun erc-capab-identify-get-unidentified-nickname (parsed) - "Return the nickname of the user if unidentified. -PARSED is an `erc-parsed' response struct." - (when (and (erc-response-p parsed) - (equal 0 (get-text-property 0 'erc-identified - (erc-response.contents parsed)))) - (let ((nickuserhost (erc-get-parsed-vector-nick parsed))) - (when nickuserhost - (nth 0 (erc-parse-user nickuserhost)))))) - -(provide 'erc-capab) - -;;; erc-capab.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-common.el b/lisp/erc/erc-common.el deleted file mode 100644 index 18f2db2a529..00000000000 --- a/lisp/erc/erc-common.el +++ /dev/null @@ -1,665 +0,0 @@ -;;; erc-common.el --- Macros and types for ERC -*- lexical-binding:t -*- - -;; Copyright (C) 2022-2025 Free Software Foundation, Inc. -;; -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, 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 3 of the License, -;; 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. If not, see . - -;;; Commentary: -;;; Code: - -(eval-when-compile (require 'cl-lib) (require 'subr-x)) -(require 'erc-compat) - -(defvar erc--casemapping-rfc1459) -(defvar erc--casemapping-rfc1459-strict) -(defvar erc-channel-users) -(defvar erc-insert-this) -(defvar erc-modules) -(defvar erc-send-this) -(defvar erc-server-process) -(defvar erc-server-users) -(defvar erc-session-server) - -(declare-function erc--get-isupport-entry "erc-backend" (key &optional single)) -(declare-function erc--init-cusr-fallback-status "erc" (v h o a q)) -(declare-function erc-get-buffer "erc" (target &optional proc)) -(declare-function erc-server-buffer "erc" nil) -(declare-function widget-apply-action "wid-edit" (widget &optional event)) -(declare-function widget-at "wid-edit" (&optional pos)) -(declare-function widget-create-child-and-convert "wid-edit" - (parent type &rest args)) -(declare-function widget-default-format-handler "wid-edit" (widget escape)) -(declare-function widget-get-sibling "wid-edit" (widget)) -(declare-function widget-move "wid-edit" (arg &optional suppress-echo)) -(declare-function widget-type "wid-edit" (widget)) - -(cl-defstruct erc-input - "Object shared among members of `erc-pre-send-functions'. -Any use outside of the hook is not supported." - ( string "" :type string - :documentation "String to send and, without `substxt', insert. -ERC treats separate lines as separate messages.") - ( insertp nil :type boolean - :documentation "Whether to insert outgoing message. -When nil, ERC still sends `string'.") - ( sendp nil :type boolean - :documentation "Whether to send and (for compat reasons) insert. -To insert without sending, define a (slash) command.") - ( substxt nil :type (or function string null) - :documentation "Alternate string to insert without splitting. -The function form is for internal use.") - ( refoldp nil :type boolean - :documentation "Whether to resplit a possibly overlong `string'. -ERC only refolds `string', never `substxt'.")) - -(cl-defstruct (erc--input-split (:include erc-input - (string "" :read-only t) - (insertp erc-insert-this) - (sendp (with-suppressed-warnings - ((obsolete erc-send-this)) - erc-send-this)))) - (lines nil :type (list-of string)) - (abortp nil :type (list-of symbol)) - (cmdp nil :type boolean)) - -(cl-defstruct (erc-server-user (:type vector) :named) - ;; User data - nickname host login full-name info - ;; Buffers - (buffers nil)) - -(cl-defstruct (erc-channel-user (:type vector) - (:constructor - erc-channel-user--make - (&key (status 0) (last-message-time nil))) - (:constructor - make-erc-channel-user - ( &key voice halfop op admin owner - last-message-time - &aux (status - (if (or voice halfop op admin owner) - (erc--init-cusr-fallback-status - voice halfop op admin owner) - 0)))) - :named) - "Object containing channel-specific data for a single user." - ;; voice halfop op admin owner - (status 0 :type integer) - ;; Last message time (in the form of the return value of - ;; (current-time) - ;; - ;; This is useful for ordered name completion. - (last-message-time nil)) - -(cl-defstruct erc--target - (string "" :type string :documentation "Received name of target.") - (symbol nil :type symbol :documentation "Case-mapped name as symbol.")) - -;; At some point, it may make sense to add a separate query type, -;; possibly with an account field to help reassociation across -;; reconnects and nick changes. - -(cl-defstruct (erc--target-channel (:include erc--target)) - (joined-p nil :type boolean :documentation "Whether channel is joined.")) - -(cl-defstruct (erc--target-channel-local (:include erc--target-channel))) - -;; Beginning in 5.5/29.1, the `tags' field may take on one of two -;; differing types. See `erc-tags-format' for details. - -(cl-defstruct (erc-response (:conc-name erc-response.)) - (unparsed "" :type string) - (sender "" :type string) - (command "" :type string) - (command-args '() :type list) - (contents "" :type string) - (tags '() :type list)) - -(cl-defstruct (erc--ctcp-response - (:include erc-response) - (:constructor - erc--ctcp-response-from-parsed - (&key parsed buffer statusmsg prefix dispname - &aux (unparsed (erc-response.unparsed parsed)) - (sender (erc-response.sender parsed)) - (command (erc-response.command parsed)) - (command-args (erc-response.command-args parsed)) - (contents (erc-response.contents parsed)) - (tags (erc-response.tags parsed))))) - "Data for a processed CTCP query or reply." - (buffer nil :type (or buffer null)) - (statusmsg nil :type (or null string)) - (prefix nil :type (or erc-channel-user null)) - (dispname nil :type (or string null))) - -(cl-defstruct erc--isupport-data - "Abstract \"class\" for parsed ISUPPORT data. -For use with the macro `erc--with-isupport-data'." - (key nil :type (or null cons))) - -(cl-defstruct (erc--parsed-prefix (:include erc--isupport-data)) - "Server-local data for recognized membership-status prefixes. -Derived from the advertised \"PREFIX\" ISUPPORT parameter." - ( letters "vhoaq" :type string - :documentation "Status letters ranked lowest to highest.") - ( statuses "+%@&~" :type string - :documentation "Status prefixes ranked lowest to highest.") - ( alist nil :type (list-of cons) - :documentation "Alist of letters-prefix pairs.")) - -(cl-defstruct (erc--channel-mode-types (:include erc--isupport-data)) - "Server-local \"CHANMODES\" data." - (fallbackp nil :type boolean) - (table (make-char-table 'erc--channel-mode-types) :type char-table) - (shortargs (make-hash-table :test #'equal))) - -;; After dropping 28, we can use prefixed "erc-autoload" cookies. -(defun erc--normalize-module-symbol (symbol) - "Return preferred SYMBOL for `erc--module'." - (while-let ((canonical (get symbol 'erc--module)) - ((not (eq canonical symbol)))) - (setq symbol canonical)) - symbol) - -(defvar erc--inside-mode-toggle-p nil - "Non-nil when a module's mode toggle is updating module membership. -This serves as a flag to inhibit the mutual recursion that would -otherwise occur between an ERC-defined minor-mode function, such -as `erc-services-mode', and the custom-set function for -`erc-modules'. For historical reasons, the latter calls -`erc-update-modules', which, in turn, enables the minor-mode -functions for all member modules. Also non-nil when a mode's -widget runs its set function.") - -(defun erc--favor-changed-reverted-modules-state (name op) - "Be more nuanced in displaying Custom state of `erc-modules'. -When `customized-value' differs from `saved-value', allow widget -to behave normally and show \"SET for current session\", as -though `customize-set-variable' or similar has been applied. -However, when `customized-value' and `standard-value' match but -differ from `saved-value', prefer showing \"CHANGED outside -Customize\" to prevent the widget from seeing a `standard' -instead of a `set' state, which precludes any actual saving." - ;; Although the button "Apply and save" is fortunately grayed out, - ;; `Custom-save' doesn't actually save (users must click the magic - ;; state button instead). The default behavior described in the doc - ;; string is intentional and was introduced by bug#12864 "Make state - ;; button interaction less confusing". However, it is unfriendly to - ;; rogue libraries (like ours) that insist on mutating user options - ;; as a matter of course. - (custom-load-symbol 'erc-modules) - (funcall (get 'erc-modules 'custom-set) 'erc-modules - (funcall op (erc--normalize-module-symbol name) erc-modules)) - (when (equal (pcase (get 'erc-modules 'saved-value) - (`((quote ,saved)) saved)) - erc-modules) - (customize-mark-as-set 'erc-modules))) - -(defun erc--assemble-toggle (localp name ablsym mode val body) - (let ((arg (make-symbol "arg"))) - `(defun ,ablsym ,(if localp `(&optional ,arg) '()) - ,(erc--fill-module-docstring - (if val "Enable" "Disable") - " ERC " (symbol-name name) " mode" (and localp " locally") "." - (when localp - (concat "\nWhen called interactively," - " do so in all buffers for the current connection."))) - (interactive ,@(when localp '("p"))) - ,@(if localp - `((when (derived-mode-p 'erc-mode) - (if ,arg - (erc-with-all-buffers-of-server erc-server-process nil - (,ablsym)) - (setq ,mode ,val) - ,@body))) - ;; No need for `default-value', etc. because a buffer-local - ;; `erc-modules' only influences the next session and - ;; doesn't survive the major-mode reset that soon follows. - `((unless - (or erc--inside-mode-toggle-p - ,@(let ((v `(memq ',(erc--normalize-module-symbol name) - erc-modules))) - `(,(if val v `(not ,v))))) - (let ((erc--inside-mode-toggle-p t)) - (erc--favor-changed-reverted-modules-state - ',name #',(if val 'cons 'delq)))) - (setq ,mode ,val) - ,@body))))) - -;; This is a migration helper that determines a module's `:group' -;; keyword argument from its name or alias. A (global) module's minor -;; mode variable appears under the group's Custom menu. Like -;; `erc--normalize-module-symbol', it must run when the module's -;; definition (rather than that of `define-erc-module') is expanded. -;; For corner cases in which this fails or the catch-all of `erc' is -;; more inappropriate, (global) modules can declare a top-level -;; -;; (put 'foo 'erc-group 'erc-bar) -;; -;; where `erc-bar' is the group and `foo' is the normalized module. -;; Do this *before* the module's definition. If `define-erc-module' -;; ever accepts arbitrary keywords, passing an explicit `:group' will -;; obviously be preferable. - -(defun erc--find-group (&rest symbols) - (catch 'found - (dolist (s symbols) - (let* ((downed (downcase (symbol-name s))) - (known (intern-soft (concat "erc-" downed)))) - (when (and known - (or (get known 'group-documentation) - (rassq known custom-current-group-alist))) - (throw 'found known)) - (when (setq known (intern-soft (concat "erc-" downed "-mode"))) - (when-let ((found (custom-group-of-mode known))) - (throw 'found found)))) - (when-let ((found (get (erc--normalize-module-symbol s) 'erc-group))) - (throw 'found found))) - 'erc)) - -;; This exists as a separate, top-level function to prevent the byte -;; compiler from warning about widget-related dependencies not being -;; loaded at runtime. - -(defun erc--tick-module-checkbox (name &rest _) ; `name' must be normalized - (customize-variable-other-window 'erc-modules) - ;; Move to `erc-modules' section. - (while (not (eq (widget-type (widget-at)) 'checkbox)) - (widget-move 1 t)) - ;; This search for a checkbox can fail when `name' refers to a - ;; third-party module that modifies `erc-modules' (improperly) on - ;; load. - (let (w) - (while (and (eq (widget-type (widget-at)) 'checkbox) - (not (and (setq w (widget-get-sibling (widget-at))) - (eq (widget-value w) name)))) - (setq w nil) - (widget-move 1 t)) ; the `suppress-echo' arg exists in 27.2 - (unless w - (error "Failed to find %s in `erc-modules' checklist" name)) - (widget-apply-action (widget-at)) - (message "Hit %s to apply or %s to apply and save." - (substitute-command-keys "\\[Custom-set]") - (substitute-command-keys "\\[Custom-save]")))) - -;; This stands apart to avoid needing forward declarations for -;; `wid-edit' functions in every file requiring `erc-common'. -(defun erc--make-show-me-widget (widget escape &rest plist) - (if (eq escape ?i) - (apply #'widget-create-child-and-convert widget 'push-button plist) - (widget-default-format-handler widget escape))) - -(defun erc--prepare-custom-module-type (name) - `(let* ((name (erc--normalize-module-symbol ',name)) - (fmtd (format " `%s' " name))) - `(boolean - :format "%{%t%}: %i %[Deprecated Toggle%] %v \n%h\n" - :format-handler - ,(lambda (widget escape) - (erc--make-show-me-widget - widget escape - :button-face '(custom-variable-obsolete custom-button) - :tag "Show Me" - :action (apply-partially #'erc--tick-module-checkbox name) - :help-echo (lambda (_) - (let ((hasp (memq name erc-modules))) - (concat (if hasp "Remove" "Add") fmtd - (if hasp "from" "to") - " `erc-modules'."))))) - :action widget-toggle-action - :documentation-property - ,(lambda (_) - (let ((hasp (memq name erc-modules))) - (concat - "Setting a module's minor-mode variable is " - (propertize "ineffective" 'face 'error) - ".\nPlease " (if hasp "remove" "add") fmtd - (if hasp "from" "to") " `erc-modules' directly instead.\n" - "You can do so now by clicking " - (propertize "Show Me" 'face 'custom-variable-obsolete) - " above.")))))) - -(defun erc--fill-module-docstring (&rest strings) - "Concatenate STRINGS and fill as a doc string." - ;; Perhaps it's better to mimic `internal--format-docstring-line' - ;; and use basic filling instead of applying a major mode? - (with-temp-buffer - (delay-mode-hooks - (if (fboundp 'lisp-data-mode) (lisp-data-mode) (emacs-lisp-mode))) - (insert (format "%S" (apply #'concat strings))) - (goto-char (point-min)) - (forward-line) - (let ((fill-column 65) - (sentence-end-double-space t)) - (fill-paragraph)) - (goto-char (point-min)) - (read (current-buffer)))) - -(defmacro erc--find-feature (name alias) - ;; Don't use this outside of the file that defines NAME. - `(pcase (erc--find-group ',name ,(and alias (list 'quote alias))) - ('erc (and-let* ((file (or (macroexp-file-name) buffer-file-name))) - (intern (file-name-base file)))) - (v v))) - -(defvar erc--module-toggle-prefix-arg nil - "The interpreted prefix arg of the minor-mode toggle. -Non-nil inside an ERC module's activation (or deactivation) -command, such as `erc-spelling-enable', when it's been called -indirectly via the module's minor-mode toggle, i.e., -`erc-spelling-mode'. nil otherwise. Its value is either the -symbol `toggle' or an integer produced by `prefix-numeric-value'. -See Info node `(elisp) Defining Minor Modes' for more.") - -(defmacro define-erc-module (name alias doc enable-body disable-body - &optional local-p) - "Define a new minor mode using ERC conventions. -Expect NAME to be the module's name and ALIAS, when non-nil, to -be a retired name used only for compatibility purposes. In new -code, assume NAME is the same symbol users should specify when -customizing `erc-modules' (see info node `(erc) Module Loading' -for more on naming). - -DOC is the documentation string to use for the minor mode. -ENABLE-BODY is a list of expressions used to enable the mode. -DISABLE-BODY is a list of expressions used to disable the mode. -If LOCAL-P is non-nil, the mode will be created as a buffer-local -mode, rather than a global one. - -This will define a minor mode called erc-NAME-mode, possibly -an alias erc-ALIAS-mode, as well as the helper functions -erc-NAME-enable, and erc-NAME-disable. - -With LOCAL-P, these helpers take on an optional argument that, -when non-nil, causes them to act on all buffers of a connection. -This feature is mainly intended for interactive use and does not -carry over to their respective minor-mode toggles. Beware that -for global modules, these helpers and toggles all mutate -`erc-modules'. - -Example: - - ;;;###autoload(autoload \\='erc-replace-mode \"erc-replace\") - (define-erc-module replace nil - \"This mode replaces incoming text according to `erc-replace-alist'.\" - ((add-hook \\='erc-insert-modify-hook - #\\='erc-replace-insert)) - ((remove-hook \\='erc-insert-modify-hook - #\\='erc-replace-insert)))" - (declare (doc-string 3) (indent defun)) - (let* ((sn (symbol-name name)) - (mode (intern (format "erc-%s-mode" (downcase sn)))) - (enable (intern (format "erc-%s-enable" (downcase sn)))) - (disable (intern (format "erc-%s-disable" (downcase sn)))) - (nmodule (erc--normalize-module-symbol name)) - (amod (and alias (intern (format "erc-%s-mode" - (downcase (symbol-name alias))))))) - `(progn - (define-minor-mode - ,mode - ,(erc--fill-module-docstring (format "Toggle ERC %s mode%s. -If called interactively, enable `%s' if ARG is positive, -and disable it otherwise. If called from Lisp, enable the mode -if ARG is omitted or nil. -\n%s" name (if local-p " locally" "") mode doc)) - :global ,(not local-p) - :group (erc--find-group ',name ,(and alias (list 'quote alias))) - ,@(unless local-p `(:require ',(erc--find-feature name alias))) - ,@(unless local-p `(:type ,(erc--prepare-custom-module-type name))) - (let ((erc--module-toggle-prefix-arg arg)) - (if ,mode (,enable) (,disable)))) - ,(erc--assemble-toggle local-p name enable mode t enable-body) - ,(erc--assemble-toggle local-p name disable mode nil disable-body) - ,@(and amod `((defalias ',amod #',mode) - (put ',amod 'erc-module ',nmodule))) - (put ',mode 'erc-module ',nmodule) - ;; For find-function and find-variable. - (put ',mode 'definition-name ',name) - (put ',enable 'definition-name ',name) - (put ',disable 'definition-name ',name)))) - -(defmacro erc-with-buffer (spec &rest body) - "Execute BODY in the buffer associated with SPEC. - -SPEC should have the form - - (TARGET [PROCESS]) - -If TARGET is a buffer, use it. Otherwise, use the buffer -matching TARGET in the process specified by PROCESS. - -If PROCESS is nil, use the current `erc-server-process'. -See `erc-get-buffer' for details. - -See also `with-current-buffer'. - -\(fn (TARGET [PROCESS]) BODY...)" - (declare (indent 1) (debug ((form &optional form) body))) - (let ((buf (make-symbol "buf")) - (proc (make-symbol "proc")) - (target (make-symbol "target")) - (process (make-symbol "process"))) - `(let* ((,target ,(car spec)) - (,process ,(cadr spec)) - (,buf (if (bufferp ,target) - ,target - (let ((,proc (or ,process - (and (processp erc-server-process) - erc-server-process)))) - (if (and ,target ,proc) - (erc-get-buffer ,target ,proc)))))) - (when (buffer-live-p ,buf) - (with-current-buffer ,buf - ,@body))))) - -(defmacro erc-with-server-buffer (&rest body) - "Execute BODY in the current ERC server buffer. -If no server buffer exists, return nil." - (declare (indent 0) (debug (body))) - (let ((varp (and (symbolp (car body)) - (not (cdr body)) - (special-variable-p (car body)))) - (buffer (make-symbol "buffer"))) - `(when-let* (((processp erc-server-process)) - (,buffer (process-buffer erc-server-process)) - ((buffer-live-p ,buffer))) - ,(if varp - `(buffer-local-value ',(car body) ,buffer) - `(with-current-buffer ,buffer - ,@body))))) - -(defmacro erc-with-all-buffers-of-server (process pred &rest forms) - "Evaluate FORMS in all buffers of PROCESS in which PRED returns non-nil. -When PROCESS is nil, do so in all ERC buffers. When PRED is nil, -run FORMS unconditionally." - (declare (indent 2) (debug (form form body))) - (macroexp-let2 nil pred pred - `(erc-buffer-filter (lambda () - (when (or (not ,pred) (funcall ,pred)) - ,@forms)) - ,process))) - -(defvar-local erc--target nil - "A permanent `erc--target' struct instance in channel and query buffers.") - -(define-inline erc-target () - "Return target of current buffer, if any, as a string." - (inline-quote (and erc--target (erc--target-string erc--target)))) - -(defun erc-log-aux (string) - "Do the debug logging of STRING." - (let ((cb (current-buffer)) - (point 1) - (was-eob nil) - (session-buffer (erc-server-buffer))) - (if session-buffer - (progn - (set-buffer session-buffer) - (defvar erc-dbuf) - (if (not (and erc-dbuf (bufferp erc-dbuf) (buffer-live-p erc-dbuf))) - (progn - (setq erc-dbuf (get-buffer-create - (concat "*ERC-DEBUG: " - erc-session-server "*"))))) - (set-buffer erc-dbuf) - (setq point (point)) - (setq was-eob (eobp)) - (goto-char (point-max)) - (insert (concat "** " string "\n")) - (if was-eob (goto-char (point-max)) - (goto-char point)) - (set-buffer cb)) - (message "ERC: ** %s" string)))) - -(defvar erc-log-p nil - "When non-nil, generate debug messages in an \"*ERC-DEBUG*\" buffer.") - -(define-inline erc-log (string) - "Logs STRING if logging is on (see `erc-log-p')." - (inline-quote - (when erc-log-p - (erc-log-aux ,string)))) - -(defun erc-downcase (string) - "Return a downcased copy of STRING with properties. -Use the CASEMAPPING ISUPPORT parameter to determine the style." - (with-case-table (pcase (erc--get-isupport-entry 'CASEMAPPING 'single) - ("ascii" ascii-case-table) - ("rfc1459-strict" erc--casemapping-rfc1459-strict) - (_ erc--casemapping-rfc1459)) - (downcase string))) - -(define-inline erc-get-channel-member (nick) - "Find NICK in the current buffer's `erc-channel-members' hash table." - (inline-quote (gethash (erc-downcase ,nick) erc-channel-users))) -(defalias 'erc-get-channel-user #'erc-get-channel-member) - -(define-inline erc-get-server-user (nick) - "Find NICK in the current server's `erc-server-users' hash table." - (inline-letevals (nick) - (inline-quote - (gethash (erc-downcase ,nick) - (erc-with-server-buffer erc-server-users))))) - -(defun erc--get-server-user (nick) - (erc-get-server-user nick)) - -(define-inline erc--remove-user-from-targets (downcased-nick buffers) - "Remove DOWNCASED-NICK from `erc-channel-members' in BUFFERS." - (inline-quote - (progn - (defvar erc-channel-members-changed-hook) - (dolist (buffer ,buffers) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (remhash ,downcased-nick erc-channel-users) - (when erc-channel-members-changed-hook - (run-hooks 'erc-channel-members-changed-hook)))))))) - -(defmacro erc--with-dependent-type-match (type &rest features) - "Massage Custom :type TYPE with :match function that pre-loads FEATURES." - `(backquote-list* ',(car type) - :match (lambda (w v) - ,@(mapcar (lambda (ft) `(require ',ft)) features) - (,(widget-get (widget-convert type) :match) w v)) - ',(cdr type))) - -;; This internal variant exists as a transition aid to avoid -;; immediately having to reflow lengthy definition lists, like the one -;; in erc.el. These sites should switch to using the public macro -;; when undergoing their next major edit. -(defmacro erc--define-catalog (name entries) - "Define `erc-display-message' formatting templates for NAME, a symbol. - -See `erc-define-message-format-catalog' for the meaning of -ENTRIES, an alist, and `erc-tests-common-pp-propertized-parts' in -tests/lisp/erc/erc-tests.el for a convenience command to convert -a literal string into a sequence of `propertize' forms, which are -much easier to review and edit. When ENTRIES begins with a -sequence of keyword-value pairs remove them and consider their -evaluated values before processing the alist proper. - -Currently, the only recognized keyword is `:parent', which tells -ERC to search recursively for a given template key using the -keyword's associated value, another catalog symbol, if not found -in catalog NAME." - (declare (indent 1)) - (let (out) - (while (keywordp (car entries)) - (push (pcase-exhaustive (pop entries) - (:parent `(put ',name 'erc--base-format-catalog - ,(pop entries)))) - out)) - (dolist (e entries (cons 'progn (nreverse out))) - (push `(defvar ,(intern (format "erc-message-%s-%s" name (car e))) - ,(cdr e) - ,(let* ((first (format "Message template for key `%s'" (car e))) - (last (format "catalog `%s'." name)) - (combined (concat first " in " last))) - (if (< (length combined) 80) - combined - (concat first ".\nFor use with " last)))) - out)))) - -(defmacro erc-define-message-format-catalog (language &rest entries) - "Define message-formatting templates for LANGUAGE, a symbol. -Expect ENTRIES to be pairs of (KEY . FORMAT), where KEY is a -symbol, and FORMAT evaluates to a format string compatible with -`format-spec'. Expect modules that only define a handful of -entries to do so manually, instead of using this macro, so that -the resulting variables will end up with more useful doc strings." - (declare (indent 1) - (debug (symbolp [&rest [keywordp form]] &rest (symbolp . form)))) - `(erc--define-catalog ,language ,entries)) - -(define-inline erc--strpos (char string) - "Return position of CHAR in STRING or nil if not found." - (inline-quote (string-search (string ,char) ,string))) - -(define-inline erc--solo (list-or-atom) - "If LIST-OR-ATOM is a list of one element, return that element. -Otherwise, return LIST-OR-ATOM." - (inline-letevals (list-or-atom) - (inline-quote - (if (and (consp ,list-or-atom) (null (cdr ,list-or-atom))) - (car ,list-or-atom) - ,list-or-atom)))) - -(defmacro erc--doarray (spec &rest body) - "Map over ARRAY, running BODY with VAR bound to iteration element. -Behave more or less like `seq-doseq', but tailor operations for -arrays. - -\(fn (VAR ARRAY [RESULT]) BODY...)" - (declare (indent 1) (debug ((symbolp form &optional form) body))) - (let ((array (make-symbol "array")) - (len (make-symbol "len")) - (i (make-symbol "i"))) - `(let* ((,array ,(nth 1 spec)) - (,len (length ,array)) - (,i 0)) - (while-let (((< ,i ,len)) - (,(car spec) (aref ,array ,i))) - ,@body - (cl-incf ,i)) - ,(nth 2 spec)))) - -(provide 'erc-common) - -;;; erc-common.el ends here diff --git a/lisp/erc/erc-compat.el b/lisp/erc/erc-compat.el deleted file mode 100644 index 4a8029d68ac..00000000000 --- a/lisp/erc/erc-compat.el +++ /dev/null @@ -1,470 +0,0 @@ -;;; erc-compat.el --- ERC compatibility code for older Emacsen -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2003, 2005-2025 Free Software Foundation, Inc. - -;; Author: Alex Schroeder -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ERC - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This mostly defines stuff that cannot be worked around easily. - -;; ERC depends on the `compat' library from GNU ELPA for supporting -;; older versions of Emacs. See this discussion for additional info: -;; https://lists.gnu.org/archive/html/emacs-devel/2022-07/msg00512.html - -;;; Code: - -(require 'compat) -(eval-when-compile (require 'cl-lib)) - -(define-obsolete-function-alias 'erc-compat-function #'compat-function "30.1") -(define-obsolete-function-alias 'erc-compat-call #'compat-call "30.1") - -;;;###autoload(autoload 'erc-define-minor-mode "erc-compat") -(define-obsolete-function-alias 'erc-define-minor-mode - #'define-minor-mode "28.1") - -(defun erc-decode-coding-string (s coding-system) - "Decode S using CODING-SYSTEM." - (declare (obsolete decode-coding-string "28.1")) - (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'." - (declare (obsolete encode-coding-string "28.1")) - (encode-coding-string s coding-system t)) - -(define-obsolete-function-alias 'erc-propertize #'propertize "28.1") -(define-obsolete-function-alias 'erc-view-mode-enter #'view-mode-enter "28.1") -(autoload 'help-function-arglist "help-fns") -(define-obsolete-function-alias 'erc-function-arglist #'help-function-arglist "28.1") -(define-obsolete-function-alias 'erc-delete-dups #'delete-dups "28.1") -(define-obsolete-function-alias 'erc-replace-regexp-in-string #'replace-regexp-in-string "28.1") - -(defun erc-set-write-file-functions (new-val) - (declare (obsolete nil "28.1")) - (setq-local write-file-functions new-val)) - -(defvar erc-emacs-build-time - (if (or (stringp emacs-build-time) (not emacs-build-time)) - emacs-build-time - (format-time-string "%Y-%m-%d" emacs-build-time)) - "Time at which Emacs was dumped out, or nil if not available.") -(make-obsolete-variable 'erc-emacs-build-time 'emacs-build-time "28.1") -(define-obsolete-variable-alias 'erc-user-emacs-directory 'user-emacs-directory "28.1") - -(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." - (declare (obsolete replace-match "28.1")) - (replace-match newtext fixedcase literal string subexp)) - -(define-obsolete-function-alias 'erc-with-selected-window - #'with-selected-window "28.1") -(define-obsolete-function-alias 'erc-cancel-timer #'cancel-timer "28.1") -(define-obsolete-function-alias 'erc-make-obsolete #'make-obsolete "28.1") -(define-obsolete-function-alias 'erc-make-obsolete-variable - #'make-obsolete-variable "28.1") - -;; Provide a simpler replacement for `cl-member-if' -(defun erc-member-if (predicate list) - "Find the first item satisfying PREDICATE in LIST. -Return the sublist of LIST whose car matches." - (declare (obsolete cl-member-if "28.1")) - (let ((ptr list)) - (catch 'found - (while ptr - (when (funcall predicate (car ptr)) - (throw 'found ptr)) - (setq ptr (cdr ptr)))))) - -;; Provide a simpler replacement for `cl-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." - (declare (obsolete cl-delete-if "28.1")) - ;; 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 `cl-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." - (declare (obsolete cl-remove-if-not "28.1")) - (let (newseq) - (dolist (el seq) - (when (funcall predicate el) - (setq newseq (cons el newseq)))) - (nreverse newseq))) - -;; 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." - (declare (obsolete cl-subseq "28.1")) - (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)))))) - - -;;;; Auth Source - -(declare-function auth-source-pass--get-attr - "auth-source-pass" (key entry-data)) -(declare-function auth-source-pass--disambiguate - "auth-source-pass" (host &optional user port)) -(declare-function auth-source-backend-parse-parameters - "auth-source-pass" (entry backend)) -(declare-function auth-source-backend "auth-source" (&rest slots)) -(declare-function auth-source-pass-entries "auth-source-pass" nil) -(declare-function auth-source-pass-parse-entry "auth-source-pass" (entry)) - -(defvar auth-sources) -(defvar auth-source-backend-parser-functions) - -;; This hard codes `auth-source-pass-port-separator' to ":" -(defun erc-compat--29-auth-source-pass--retrieve-parsed (seen e port-number-p) - (when (string-match (rx (or bot "/") - (or (: (? (group-n 20 (+ (not (in "/:")))) "@") - (group-n 10 (+ (not (in "/:@")))) - (? ":" (group-n 30 (+ (not (in " /:")))))) - (: (group-n 11 (+ (not (in "/:@")))) - (? ":" (group-n 31 (+ (not (in " /:"))))) - (? "/" (group-n 21 (+ (not (in "/:"))))))) - eot) - e) - (puthash e `( :host ,(or (match-string 10 e) (match-string 11 e)) - ,@(if-let* ((tr (match-string 21 e))) - (list :user tr :suffix t) - (list :user (match-string 20 e))) - :port ,(and-let* ((p (or (match-string 30 e) - (match-string 31 e))) - (n (string-to-number p))) - (if (or (zerop n) (not port-number-p)) - (format "%s" p) - n))) - seen))) - -;; This looks bad, but it just inlines `auth-source-pass--find-match-many'. -(defun erc-compat--29-auth-source-pass--build-result-many - (hosts users ports require max) - "Return a plist of HOSTS, PORTS, USERS, and secret." - (unless (listp hosts) (setq hosts (list hosts))) - (unless (listp users) (setq users (list users))) - (unless (listp ports) (setq ports (list ports))) - (unless max (setq max 1)) - (let ((seen (make-hash-table :test #'equal)) - (entries (auth-source-pass-entries)) - (check (lambda (m k v) - (let ((mv (plist-get m k))) - (if (memq k require) - (and v (equal mv v)) - (or (not v) (not mv) (equal mv v)))))) - out suffixed suffixedp) - (catch 'done - (dolist (host hosts) - (pcase-let ((`(,_ ,u ,p) (auth-source-pass--disambiguate host))) - (unless (or (not (equal "443" p)) (string-prefix-p "https://" host)) - (setq p nil)) - (dolist (user (or users (list u))) - (dolist (port (or ports (list p))) - (dolist (e entries) - (when-let* - ((m (or (gethash e seen) - (erc-compat--29-auth-source-pass--retrieve-parsed - seen e (integerp port)))) - ((equal host (plist-get m :host))) - ((funcall check m :port port)) - ((funcall check m :user user)) - (parsed (auth-source-pass-parse-entry e)) - (secret (or (auth-source-pass--get-attr 'secret parsed) - (not (memq :secret require))))) - (push - `( :host ,host ; prefer user-provided :host over h - ,@(and-let* ((u (plist-get m :user))) (list :user u)) - ,@(and-let* ((p (plist-get m :port))) (list :port p)) - ,@(and secret (not (eq secret t)) (list :secret secret))) - (if (setq suffixedp (plist-get m :suffix)) suffixed out)) - (unless suffixedp - (when (or (zerop (cl-decf max)) - (null (setq entries (delete e entries)))) - (throw 'done out))))) - (setq suffixed (nreverse suffixed)) - (while suffixed - (push (pop suffixed) out) - (when (zerop (cl-decf max)) - (throw 'done out)))))))) - (reverse out))) - -(cl-defun erc-compat--29-auth-source-pass-search - (&rest spec &key host user port require max &allow-other-keys) - ;; From `auth-source-pass-search' - (cl-assert (and host (not (eq host t))) - t "Invalid password-store search: %s %s") - (let ((rv (erc-compat--29-auth-source-pass--build-result-many - host user port require max))) - (if (and (fboundp 'auth-source--obfuscate) - (fboundp 'auth-source--deobfuscate)) - (let (out) - (dolist (e rv out) - (when-let* ((s (plist-get e :secret)) - (v (auth-source--obfuscate s))) - (setq e (plist-put e :secret (apply-partially - #'auth-source--deobfuscate v)))) - (push e out))) - rv))) - -(defun erc-compat--29-auth-source-pass-backend-parse (entry) - (when (eq entry 'password-store) - (auth-source-backend-parse-parameters - entry (auth-source-backend - :source "." - :type 'password-store - :search-function #'erc-compat--29-auth-source-pass-search)))) - -(defun erc-compat--auth-source-backend-parser-functions () - (if (memq 'password-store auth-sources) - (progn - (require 'auth-source-pass) - `(,@(unless (bound-and-true-p auth-source-pass-extra-query-keywords) - '(erc-compat--29-auth-source-pass-backend-parse)) - ,@auth-source-backend-parser-functions)) - auth-source-backend-parser-functions)) - - -;;;; SASL - -(declare-function sasl-step-data "sasl" (step)) -(declare-function sasl-error "sasl" (datum)) -(declare-function sasl-client-property "sasl" (client property)) -(declare-function sasl-client-set-property "sasl" (client property value)) -(declare-function sasl-mechanism-name "sasl" (mechanism)) -(declare-function sasl-client-name "sasl" (client)) -(declare-function sasl-client-mechanism "sasl" (client)) -(declare-function sasl-read-passphrase "sasl" (prompt)) -(declare-function sasl-unique-id "sasl" nil) -(declare-function decode-hex-string "hex-util" (string)) -(declare-function rfc2104-hash "rfc2104" (hash block-length hash-length - key text)) -(declare-function sasl-scram--client-first-message-bare "sasl-scram-rfc" - (client)) -(declare-function cl-mapcar "cl-lib" (cl-func cl-x &rest cl-rest)) - -(defun erc-compat--29-sasl-scram-construct-gs2-header (client) - (let ((authzid (sasl-client-property client 'authenticator-name))) - (concat "n," (and authzid "a=") authzid ","))) - -(defun erc-compat--29-sasl-scram-client-first-message (client _step) - (let ((c-nonce (sasl-unique-id))) - (sasl-client-set-property client 'c-nonce c-nonce)) - (concat (erc-compat--29-sasl-scram-construct-gs2-header client) - (sasl-scram--client-first-message-bare client))) - -(defun erc-compat--29-sasl-scram--client-final-message - (hash-fun block-length hash-length client step) - (unless (string-match - "^r=\\([^,]+\\),s=\\([^,]+\\),i=\\([0-9]+\\)\\(?:$\\|,\\)" - (sasl-step-data step)) - (sasl-error "Unexpected server response")) - (let* ((hmac-fun - (lambda (text key) - (decode-hex-string - (rfc2104-hash hash-fun block-length hash-length key text)))) - (step-data (sasl-step-data step)) - (nonce (match-string 1 step-data)) - (salt-base64 (match-string 2 step-data)) - (iteration-count (string-to-number (match-string 3 step-data))) - (c-nonce (sasl-client-property client 'c-nonce)) - (cbind-input - (if (string-prefix-p c-nonce nonce) - (erc-compat--29-sasl-scram-construct-gs2-header client) ; *1 - (sasl-error "Invalid nonce from server"))) - (client-final-message-without-proof - (concat "c=" (base64-encode-string cbind-input t) "," ; *2 - "r=" nonce)) - (password - (sasl-read-passphrase - (format "%s passphrase for %s: " - (sasl-mechanism-name (sasl-client-mechanism client)) - (sasl-client-name client)))) - (salt (base64-decode-string salt-base64)) - (string-xor (lambda (a b) - (apply #'unibyte-string (cl-mapcar #'logxor a b)))) - (salted-password (let ((digest (concat salt (string 0 0 0 1))) - (xored nil)) - (dotimes (_i iteration-count xored) - (setq digest (funcall hmac-fun digest password)) - (setq xored (if (null xored) - digest - (funcall string-xor xored - digest)))))) - (client-key (funcall hmac-fun "Client Key" salted-password)) - (stored-key (decode-hex-string (funcall hash-fun client-key))) - (auth-message (concat "n=" (sasl-client-name client) - ",r=" c-nonce "," step-data - "," client-final-message-without-proof)) - (client-signature (funcall hmac-fun - (encode-coding-string auth-message 'utf-8) - stored-key)) - (client-proof (funcall string-xor client-key client-signature)) - (client-final-message - (concat client-final-message-without-proof "," - "p=" (base64-encode-string client-proof t)))) ; *3 - (sasl-client-set-property client 'auth-message auth-message) - (sasl-client-set-property client 'salted-password salted-password) - client-final-message)) - - -;;;; Misc 28.1 - -(defmacro erc-compat--xml-escape-string (string &optional noerror) - "Call `xml-escape-string' with NO-ERROR if supported." - (if (>= emacs-major-version 28) - `(xml-escape-string ,string ,noerror) - `(xml-escape-string ,string))) - - -;;;; Misc 29.1 - -(defvar url-irc-function) -(declare-function url-type "url-parse" (cl-x)) - -(defun erc-compat--29-browse-url-irc (string &rest _) - (require 'url-irc) - (let* ((url (url-generic-parse-url string)) - (url-irc-function - (if (eq url-irc-function 'url-irc-erc) - (lambda (host port chan user pass) - (erc-handle-irc-url host port chan user pass (url-type url))) - url-irc-function))) - (url-irc url))) - -(cond ((fboundp 'browse-url-irc)) ; 29 - ((boundp 'browse-url-default-handlers) ; 28 - (add-to-list 'browse-url-default-handlers - '("\\`irc6?s?://" . erc-compat--29-browse-url-irc) - nil (lambda (_ a) - (and (stringp (car-safe a)) - (string-match-p (car a) "irc://localhost"))))) - ((boundp 'browse-url-browser-function) ; 27 - (require 'browse-url) - (let ((existing browse-url-browser-function)) - (setq browse-url-browser-function - (if (functionp existing) - (lambda (u &rest r) - (apply (if (string-match-p "\\`irc6?s?://" u) - #'erc-compat--29-browse-url-irc - existing) - u r)) - (cons '("\\`irc6?s?://" . erc-compat--29-browse-url-irc) - existing)))))) - -;; We can't store (TICKS . HZ) style timestamps on 27 and 28 because -;; `time-less-p' and friends do -;; -;; message("obsolete timestamp with cdr ...", ...) -;; decode_lisp_time(_, WARN_OBSOLETE_TIMESTAMPS, ...) -;; lisp_time_struct(...) -;; time_cmp(...) -;; -;; which spams *Messages* (and stderr when running the test suite). -(defmacro erc-compat--current-lisp-time () - "Return `current-time' as a (TICKS . HZ) pair on 29+." - (if (>= emacs-major-version 29) - '(let (current-time-list) (current-time)) - '(current-time))) - -(defmacro erc-compat--defer-format-spec-in-buffer (&rest spec) - "Transform SPEC forms into functions that run in the current buffer. -For convenience, ensure function wrappers return \"\" as a -fallback." - (cl-check-type (car spec) cons) - (let ((buffer (make-symbol "buffer"))) - `(let ((,buffer (current-buffer))) - ,(list '\` - (mapcar - (pcase-lambda (`(,k . ,v)) - (cons k - (list '\,(if (>= emacs-major-version 29) - `(lambda () - (or (if (eq ,buffer (current-buffer)) - ,v - (with-current-buffer ,buffer - ,v)) - "")) - `(or ,v ""))))) - spec))))) - - -;;;; Misc 31.1 - -(defun erc-compat--window-no-other-p (window) - ;; See bug#73706. - (if (fboundp 'window-no-other-p) - (window-no-other-p window) - (setq window (window-normalize-window window t)) - (and (not ignore-window-parameters) - (window-parameter window 'no-other-window)))) - - -(provide 'erc-compat) - -;;; erc-compat.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-dcc.el b/lisp/erc/erc-dcc.el deleted file mode 100644 index 049e5ff457e..00000000000 --- a/lisp/erc/erc-dcc.el +++ /dev/null @@ -1,1285 +0,0 @@ -;;; erc-dcc.el --- CTCP DCC module for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 1993-2025 Free Software Foundation, Inc. - -;; Author: Ben A. Mesander -;; Noah Friedman -;; Per Persson -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; Created: 1994-01-23 - -;; This file is part of GNU Emacs. - -;; GNU Emacs is free software: you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published by -;; the Free Software Foundation, either version 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file provides Direct Client-to-Client support for ERC. -;; -;; The original code was taken from zenirc-dcc.el, heavily mangled and -;; rewritten to support the way how ERC operates. Server socket support -;; was added for DCC CHAT and SEND afterwards. Thanks -;; to the original authors for their work. - -;;; Usage: - -;; To use this file, put -;; (require 'erc-dcc) -;; in your .emacs. -;; -;; Provided commands -;; /dcc chat nick - Either accept pending chat offer from nick, or offer -;; DCC chat to nick -;; /dcc close type [nick] - Close DCC connection (SEND/GET/CHAT) with nick -;; /dcc get [-t][-s] nick [--] file - Accept DCC offer from nick -;; /dcc list - List all DCC offers/connections -;; /dcc send nick file - Offer DCC SEND to nick - -;;; Code: - -(require 'erc) -;; Strictly speaking, should only be needed at compile time. -;; Require at run-time too to silence compiler. -(require 'pcomplete) - -(defgroup erc-dcc nil - "DCC stands for Direct Client Communication, where you and your -friend's client programs connect directly to each other, -bypassing IRC servers and their occasional \"lag\" or \"split\" -problems. Like /MSG, the DCC chat is completely private. - -Using DCC get and send, you can transfer files directly from and to other -IRC users." - :group 'erc) - -;;;###autoload(autoload 'erc-dcc-mode "erc-dcc") -(define-erc-module dcc nil - "Provide Direct Client-to-Client support for ERC." - ((add-hook 'erc-server-401-functions #'erc-dcc-no-such-nick)) - ((remove-hook 'erc-server-401-functions #'erc-dcc-no-such-nick))) - -(defcustom erc-dcc-verbose nil - "If non-nil, be verbose about DCC activity reporting." - :type 'boolean) - -(defconst erc-dcc-connection-types - '("CHAT" "GET" "SEND") - "List of valid DCC connection types. -All values of the list must be uppercase strings.") - -(defvar erc-dcc-list nil - "List of DCC connections. -Looks like: - ((:nick \"nick!user@host\" :type GET :peer proc - :parent proc :size size :file file) - (:nick \"nick!user@host\" :type CHAT :peer proc :parent proc) - (:nick \"nick\" :type SEND :peer server-proc :parent parent-proc :file - file :sent :confirmed )) - - :nick - a user or userhost for the peer. Combine with :parent to reach them - - :type - the type of DCC connection - SEND for outgoing files, GET for - incoming, and CHAT for both directions. To tell which end started - the DCC chat, look at :peer - - :peer - the other end of the DCC connection. In the case of outgoing DCCs, - this represents a server process until a connection is established - - :parent - the server process where the dcc connection was established. - Note that this can be nil or an invalid process since a DCC - connection is in general independent from a particular server - connection after it was established. - - :file - for outgoing sends, the full path to the file. For incoming sends, - the suggested filename or vetted filename - - :size - size of the file, may be nil on incoming DCCs - - :secure - optional item indicating sender support for TLS - - :turbo - optional item indicating sender support for TSEND") - -(defun erc-dcc-list-add (type nick peer parent &rest args) - "Add a new entry of type TYPE to `erc-dcc-list' and return it." - (car - (setq erc-dcc-list - (cons - (append (list :nick nick :type type :peer peer :parent parent) args) - erc-dcc-list)))) - -;; This function takes all the usual args as open-network-stream, plus one -;; more: the entry data from erc-dcc-list for this particular process. -(defvar erc-dcc-connect-function 'erc-dcc-open-network-stream) - -(defun erc-dcc-open-network-stream (procname buffer addr port entry) - ;; FIXME: Time to try activating this again!? - (if nil; (fboundp 'open-network-stream-nowait) ;; this currently crashes - ;; cvs emacs - (open-network-stream-nowait procname buffer addr port) - (open-network-stream procname buffer addr port - :type (and (plist-get entry :secure) 'tls)))) - -(erc--define-catalog english - ((dcc-chat-discarded - . "DCC: previous chat request from %n (%u@%h) discarded") - (dcc-chat-ended . "DCC: chat with %n ended %t: %e") - (dcc-chat-no-request . "DCC: chat request from %n not found") - (dcc-chat-offered . "DCC: chat offered by %n (%u@%h:%p)") - (dcc-chat-offer . "DCC: offering chat to %n") - (dcc-chat-accept . "DCC: accepting chat from %n") - (dcc-chat-privmsg . "=%n= %m") - (dcc-closed . "DCC: Closed %T from %n") - (dcc-command-undefined - . "DCC: %c undefined subcommand. GET, CHAT and LIST are defined.") - (dcc-ctcp-errmsg . "DCC: `%s' is not a DCC subcommand known to this client") - (dcc-ctcp-unknown . "DCC: unknown dcc command `%q' from %n (%u@%h)") - (dcc-get-bytes-received . "DCC: %f: %b bytes received") - (dcc-get-complete - . "DCC: file %f transfer complete (%s bytes in %t seconds)") - (dcc-get-failed . "DCC: file %f transfer failed at %s of %v in %t seconds") - (dcc-get-cmd-aborted . "DCC: Aborted getting %f from %n") - (dcc-get-file-too-long - . "DCC: %f: File longer than sender claimed; aborting transfer") - (dcc-get-notfound . "DCC: %n hasn't offered %f for DCC transfer") - (dcc-list-head . "DCC: From Type Active Size Filename") - (dcc-list-line . "DCC: -------- ---- ------ ----------------- --------") - (dcc-list-item . "DCC: %-8n %-4t %-6a %-17s %f%u") - (dcc-list-end . "DCC: End of list.") - (dcc-malformed . "DCC: error: %n (%u@%h) sent malformed request: %q") - (dcc-privileged-port - . "DCC: possibly bogus request: %p is a privileged port.") - (dcc-request-bogus . "DCC: bogus dcc `%r' from %n (%u@%h)") - (dcc-send-finished . "DCC: SEND of %f to %n finished (size %s)") - (dcc-send-offered . "DCC: file %f offered by %n (%u@%h) (size %s)") - (dcc-send-offer . "DCC: offering %f to %n"))) - -;;; Misc macros and utility functions - -(defun erc-dcc-member (&rest args) - "Return first matching entry in `erc-dcc-list' satisfying constraints in ARGS. -ARGS is a plist. Return nil on no match. - -The property :nick is treated specially, if it contains a `!' character, -it is treated as a nick!user@host string, and compared with the :nick property -value of the individual elements using `string-equal'. Otherwise it is -compared with `erc-nick-equal-p' which is IRC case-insensitive." - (let ((list erc-dcc-list) - result test) - ;; for each element in erc-dcc-list - (while (and list (not result)) - (let ((elt (car list)) - (prem args) - (cont t)) - ;; loop through the constraints - (while (and prem cont) - (let ((prop (car prem)) - (val (cadr prem))) - (setq prem (cddr prem) - test (cadr (plist-member elt prop))) - ;; if the property exists and is equal, we continue, else, try the - ;; next element of the list - (or (and (eq prop :nick) (string-search "!" val) - test (string-equal test val)) - (and (eq prop :nick) - test val - (erc-nick-equal-p - (erc-extract-nick test) - (erc-extract-nick val))) - ;; not a nick - (equal test val) - (setq cont nil)))) - (if cont - (setq result elt) - (setq list (cdr list))))) - result)) - -(defun erc-pack-int (value) - "Convert integer into a packed string in network byte order, which is big-endian." - ;; make sure value is not negative - (when (< value 0) - (error "ERC-DCC (erc-pack-int): packet size is negative")) - ;; make sure size is not larger than 4 bytes - (let ((len (if (= value 0) 0 - (ceiling (/ (ceiling (/ (log value) (log 2))) 8.0))))) - (when (> len 4) - (error "ERC-DCC (erc-pack-int): packet too large"))) - ;; pack - (let ((str (make-string 4 0)) - (i 3)) - (while (and (>= i 0) (> value 0)) - (aset str i (% value 256)) - (setq value (/ value 256)) - (setq i (1- i))) - str)) - -(defun erc-unpack-int (str) - "Unpack a packed string into an integer." - (let ((len (length str))) - ;; strip leading 0-bytes - (let ((start 0)) - (while (and (> len start) (eq (aref str start) 0)) - (setq start (1+ start))) - (when (> start 0) - (setq str (substring str start)) - (setq len (- len start)))) - ;; unpack - (let ((num 0) - (count 0)) - (while (< count len) - (setq num (+ num (ash (aref str (- len count 1)) (* 8 count)))) - (setq count (1+ count))) - num))) - -(defconst erc-dcc-ipv4-regexp - (concat "^" - (mapconcat #'identity (make-list 4 "\\([0-9]\\{1,3\\}\\)") "\\.") - "$")) - -(defun erc-ip-to-decimal (ip) - "Convert IP address to its decimal representation. -Argument IP is the address as a string. The result is also a string." - (interactive "sIP Address: ") - (if (not (string-match erc-dcc-ipv4-regexp ip)) - (error "Not an IP address") - (let* ((ips (mapcar - (lambda (str) - (let ((n (string-to-number str))) - (if (and (>= n 0) (< n 256)) - n - (error "%d out of range" n)))) - (split-string ip "\\."))) - (res (+ (* (car ips) 16777216.0) - (* (nth 1 ips) 65536.0) - (* (nth 2 ips) 256.0) - (nth 3 ips)))) - (if (called-interactively-p 'interactive) - (message "%s is %.0f" ip res) - (format "%.0f" res))))) - -(defun erc-decimal-to-ip (dec) - "Convert a decimal representation DEC to an IP address. -The result is also a string." - (when (stringp dec) - (setq dec (string-to-number (concat dec ".0")))) - (let* ((first (floor (/ dec 16777216.0))) - (first-rest (- dec (* first 16777216.0))) - (second (floor (/ first-rest 65536.0))) - (second-rest (- first-rest (* second 65536.0))) - (third (floor (/ second-rest 256.0))) - (third-rest (- second-rest (* third 256.0))) - (fourth (floor third-rest))) - (format "%s.%s.%s.%s" first second third fourth))) - -;;; Server code - -(defcustom erc-dcc-listen-host nil - "IP address to listen on when offering files. -Should be set to a string or nil. If nil, automatic detection of -the host interface to use will be attempted." - :type (list 'choice (list 'const :tag "Auto-detect" nil) - (list 'string :tag "IP-address" - :valid-regexp erc-dcc-ipv4-regexp))) - -(defcustom erc-dcc-public-host nil - "IP address to use for outgoing DCC offers. -Should be set to a string or nil. If nil, use the value of -`erc-dcc-listen-host'." - :type (list 'choice (list 'const :tag "Same as erc-dcc-listen-host" nil) - (list 'string :tag "IP-address" - :valid-regexp erc-dcc-ipv4-regexp))) - -(defcustom erc-dcc-send-request 'ask - "How to treat incoming DCC Send requests. -`ask' - Report the Send request, and wait for the user to manually accept it - You might want to set `erc-dcc-auto-masks' for this. -`auto' - Automatically accept the request and begin downloading the file -`ignore' - Ignore incoming DCC Send requests completely." - :type '(choice (const ask) (const auto) (const ignore))) - -(defun erc-dcc-get-host (proc) - "Return the local IP address used for an open process PROC." - (format-network-address (process-contact proc :local) t)) - -(defun erc-dcc-host () - "Determine the IP address we are using. -If variable `erc-dcc-host' is non-nil, use it. Otherwise call -`erc-dcc-get-host' on the erc-server-process." - (or erc-dcc-listen-host (erc-dcc-get-host erc-server-process) - (error "Unable to determine local address"))) - -(defcustom erc-dcc-port-range nil - "If nil, any available user port is used for outgoing DCC connections. -If set to a cons, it specifies a range of ports to use in the form (min . max)" - :type '(choice - (const :tag "Any port" nil) - (cons :tag "Port range" - (integer :tag "Lower port") - (integer :tag "Upper port")))) - -(defcustom erc-dcc-auto-masks nil - "List of regexps matching user identifiers whose DCC send offers should be -accepted automatically. A user identifier has the form \"nick!login@host\". -For instance, to accept all incoming DCC send offers automatically, add the -string \".*!.*@.*\" to this list." - :type '(repeat regexp)) - -(defun erc-dcc-server (name filter sentinel) - "Start listening on a port for an incoming DCC connection. -Returns the newly created subprocess, or nil." - (let ((port (or (and erc-dcc-port-range (car erc-dcc-port-range)) t)) - (upper (and erc-dcc-port-range (cdr erc-dcc-port-range))) - process) - (while (not process) - (condition-case err - (progn - (setq process - (make-network-process :name name - :buffer nil - :host (erc-dcc-host) - :service port - :noquery nil - :filter filter - :sentinel sentinel - :log #'erc-dcc-server-accept - :server t)) - (when (processp process) - (when (fboundp 'set-process-coding-system) - (set-process-coding-system process 'binary 'binary)))) - (file-error - (unless (and (string= "Cannot bind server socket" (nth 1 err)) - (string= "address already in use" (downcase (nth 2 err)))) - (signal (car err) (cdr err))) - (setq port (1+ port)) - (unless (< port upper) - (error "No available ports in erc-dcc-port-range"))))) - process)) - -(defun erc-dcc-server-accept (server client message) - "Log an accepted DCC offer, then terminate the listening process and set up -the accepted connection." - (erc-log (format "(erc-dcc-server-accept): server %s client %s message %s" - server client message)) - (when (and (string-match "^accept from " message) - (processp server) (processp client)) - (let ((elt (erc-dcc-member :peer server))) - ;; change the entry in erc-dcc-list from the listening process to the - ;; accepted process - (setq elt (plist-put elt :peer client)) - ;; delete the listening process, as we've accepted the connection - (delete-process server)))) - -;;; Interactive command handling - -(defcustom erc-dcc-get-default-directory nil - "Default directory for incoming DCC file transfers. -If this is nil, then the current value of `default-directory' is used." - :type '(choice (const :value nil :tag "Default directory") directory)) - -(autoload 'pcomplete-erc-all-nicks "erc-pcomplete") - -;;;###autoload -(defun pcomplete/erc-mode/DCC () - "Provide completion for the /DCC command." - (pcomplete-here (append '("chat" "close" "get" "list") - (when (fboundp 'make-network-process) '("send")))) - (when (equal "get" (downcase (pcomplete-arg 1))) - (pcomplete-opt "ts") - (pcomplete-opt (if (equal "-s" (pcomplete-arg 'first 2)) "t" "s"))) - (pcomplete-here - (pcase (intern (downcase (pcomplete-arg 'first 1))) - ('chat (mapcar (lambda (elt) (plist-get elt :nick)) - (cl-remove-if-not - (lambda (elt) - (eq (plist-get elt :type) 'CHAT)) - erc-dcc-list))) - ('close (delete-dups - (mapcar (lambda (elt) (symbol-name (plist-get elt :type))) - erc-dcc-list))) - ('get (mapcar #'erc-dcc-nick - (cl-remove-if-not - (lambda (elt) - (eq (plist-get elt :type) 'GET)) - erc-dcc-list))) - ('send (pcomplete-erc-all-nicks)))) - (when (equal "get" (downcase (pcomplete-arg 'first 1))) - (pcomplete-opt "-")) - (pcomplete-here - (pcase (intern (downcase (pcomplete-arg 'first 1))) - ('get (mapcar (lambda (elt) - (combine-and-quote-strings (list (plist-get elt :file)))) - (cl-remove-if-not - (lambda (elt) - (and (eq (plist-get elt :type) 'GET) - (erc-nick-equal-p (erc-extract-nick - (plist-get elt :nick)) - (pcase (pcomplete-arg 1) - ("--" (pcomplete-arg 2)) - (v v))))) - erc-dcc-list))) - ('close (mapcar #'erc-dcc-nick - (cl-remove-if-not - (lambda (elt) - (eq (plist-get elt :type) - (intern (upcase (pcomplete-arg 1))))) - erc-dcc-list))) - ('send (pcomplete-entries))))) - -(defun erc-dcc-do-CHAT-command (proc &optional nick) - (when nick - (let ((elt (erc-dcc-member :nick nick :type 'CHAT :parent proc))) - (if (and elt (not (processp (plist-get elt :peer)))) - ;; accept an existing chat offer - ;; FIXME: perhaps /dcc accept like other clients? - (progn (erc-dcc-chat-accept elt erc-server-process) - (erc-display-message - nil 'notice 'active - 'dcc-chat-accept ?n nick) - t) - (erc-dcc-chat nick erc-server-process) - (erc-display-message - nil 'notice 'active - 'dcc-chat-offer ?n nick) - t)))) - -(defun erc-dcc-do-CLOSE-command (_proc &optional type nick) - "Close a connection. Usage: /dcc close type nick. -At least one of TYPE and NICK must be provided." - ;; disambiguate type and nick if only one is provided - (when (and type (null nick) - (not (member (upcase type) erc-dcc-connection-types))) - (setq nick type) - (setq type nil)) - ;; validate nick argument - (unless (and nick (string-match (concat "\\`" erc-valid-nick-regexp "\\'") - nick)) - (setq nick nil)) - ;; validate type argument - (if (and type (member (upcase type) erc-dcc-connection-types)) - (setq type (intern (upcase type))) - (setq type nil)) - (when (or nick type) - (let ((ret t)) - (while ret - (cond ((and nick type) - (setq ret (erc-dcc-member :type type :nick nick))) - (nick - (setq ret (erc-dcc-member :nick nick))) - (type - (setq ret (erc-dcc-member :type type))) - (t - (setq ret nil))) - (when ret - ;; found a match - delete process if it exists. - (and (processp (plist-get ret :peer)) - (delete-process (plist-get ret :peer))) - (setq erc-dcc-list (delq ret erc-dcc-list)) - (erc-display-message - nil 'notice 'active - 'dcc-closed - ?T (plist-get ret :type) - ?n (erc-extract-nick (plist-get ret :nick)))))) - t)) - -(defun erc-dcc-do-GET-command (proc &rest args) - "Perform a DCC GET command. -Recognize input conforming to the following usage syntax: - - /DCC GET [-t|-s] nick [--] filename - - nick The person who is sending the file. - filename The filename to be downloaded. Can be split into multiple - arguments that are then joined by a space. - flags \"-t\" sets `:turbo' in `erc-dcc-list' - \"-s\" sets `:secure' in `erc-dcc-list' - \"--\" indicates end of options - All of which are optional. - -Expect PROC to be the server process and ARGS to contain -everything after the subcommand \"GET\" in the usage description -above." - ;; Despite the advertised syntax above, we currently respect flags - ;; in these positions: [flag] nick [flag] filename [flag] - (let* ((trailing (and-let* ((trailing (member "--" args))) - (setq args (butlast args (length trailing))) - (cdr trailing))) - (args (seq-group-by (lambda (s) (eq ?- (aref s 0))) args)) - (flags (prog1 (cdr (assq t args)) - (setq args (nconc (cdr (assq nil args)) trailing)))) - (nick (pop args)) - (file (and args (mapconcat #'identity args " "))) - (elt (erc-dcc-member :nick nick :type 'GET :file file)) - (filename (or file (plist-get elt :file) "unknown"))) - (if elt - (let* ((file (read-file-name - (format-prompt "Local filename" - (file-name-nondirectory filename)) - (or erc-dcc-get-default-directory - default-directory) - (expand-file-name (file-name-nondirectory filename) - (or erc-dcc-get-default-directory - default-directory))))) - (cond ((file-exists-p file) - (if (yes-or-no-p (format "File %s exists. Overwrite? " - file)) - (erc-dcc-get-file elt file proc) - (erc-display-message - nil '(notice error) proc - 'dcc-get-cmd-aborted - ?n nick ?f filename))) - (t - (erc-dcc-get-file elt file proc))) - (when (member "-s" flags) - (setq erc-dcc-list (cons (plist-put elt :secure t) - (delq elt erc-dcc-list)))) - (when (member "-t" flags) - (setq erc-dcc-list (cons (plist-put elt :turbo t) - (delq elt erc-dcc-list))))) - (erc-display-message - nil '(notice error) 'active - 'dcc-get-notfound ?n nick ?f filename)))) - -(defvar-local erc-dcc-byte-count nil) - -(defun erc-dcc-do-LIST-command (_proc) - "This is the handler for the /dcc list command. -It lists the current state of `erc-dcc-list' in an easy to read manner." - (let ((alist erc-dcc-list) - size elt) - (erc-display-message - nil 'notice 'active - 'dcc-list-head) - (erc-display-message - nil 'notice 'active - 'dcc-list-line) - (while alist - (setq elt (car alist) - alist (cdr alist)) - - (setq size (or (and (plist-member elt :size) - (plist-get elt :size)) - "")) - (setq size - (cond ((null size) "") - ((numberp size) (number-to-string size)) - ((string= size "") "unknown"))) - (erc-display-message - nil 'notice 'active - 'dcc-list-item - ?n (erc-dcc-nick elt) - ?t (plist-get elt :type) - ?a (if (processp (plist-get elt :peer)) - (process-status (plist-get elt :peer)) - "no") - ?s (concat size - ;; FIXME consider uniquified names, e.g., foo.bin<2> - (if (and (eq 'GET (plist-get elt :type)) - (plist-member elt :file) - (buffer-live-p (get-buffer (plist-get elt :file))) - (plist-member elt :size)) - (let ((byte-count (with-current-buffer - (plist-get elt :file) - (+ (buffer-size) 0.0 - erc-dcc-byte-count)))) - (format " (%d%%)" - (floor (* 100.0 byte-count) - (plist-get elt :size)))))) - ?f (or (and (plist-member elt :file) (plist-get elt :file)) "") - ?u (if-let* ((flags (concat (and (plist-get elt :turbo) "t") - (and (plist-get elt :secure) "s"))) - ((not (string-empty-p flags)))) - (concat " (" flags ")") - ""))) - (erc-display-message - nil 'notice 'active - 'dcc-list-end) - t)) - -(defun erc-dcc-do-SEND-command (proc nick &rest file) - "Offer FILE to NICK by sending a ctcp dcc send message. -If FILE is split into multiple arguments, re-join the arguments, -separated by a space." - (setq file (and file (mapconcat #'identity file " "))) - (if (file-exists-p file) - (progn - (erc-display-message - nil 'notice 'active - 'dcc-send-offer ?n nick ?f file) - (erc-dcc-send-file nick file) t) - (erc-display-message nil '(notice error) proc "File not found") t)) - -;;; Server message handling (i.e. messages from remote users) - -;;;###autoload -(defvar erc-ctcp-query-DCC-hook '(erc-ctcp-query-DCC) - "Hook variable for CTCP DCC queries.") - -(defvar erc-dcc-query-handler-alist - '(("SEND" . erc-dcc-handle-ctcp-send) - ("TSEND" . erc-dcc-handle-ctcp-send) - ("SSEND" . erc-dcc-handle-ctcp-send) - ("TSSEND" . erc-dcc-handle-ctcp-send) - ("STSEND" . erc-dcc-handle-ctcp-send) - ("CHAT" . erc-dcc-handle-ctcp-chat))) - -;;;###autoload -(defun erc-ctcp-query-DCC (proc nick login host to query) - "The function called when a CTCP DCC request is detected by the client. -It examines the DCC subcommand, and calls the appropriate routine for -that subcommand." - (let* ((cmd (cadr (split-string query " "))) - (handler (cdr (assoc cmd erc-dcc-query-handler-alist)))) - (if handler - (funcall handler proc query nick login host to) - ;; FIXME: Send a ctcp error notice to the remote end? - (erc-display-message - nil '(notice error) proc - 'dcc-ctcp-unknown - ?q query ?n nick ?u login ?h host)))) - -(defconst erc-dcc-ctcp-query-send-regexp - (rx bot "DCC " (group-n 6 (: (** 0 2 (any "TS")) "SEND")) " " - ;; Following part matches either filename without spaces - ;; or filename enclosed in double quotes with any number - ;; of escaped double quotes inside. - (: (or (: ?\" (group-n 1 (+ (or (: ?\\ ?\") (not (any ?\" ?\\))))) ?\") - (group-n 2 (+ (not " "))))) - (: " " (group-n 3 (+ digit)) - " " (group-n 4 (+ digit)) - (* " ") (group-n 5 (* digit))) - eot)) - -(define-inline erc-dcc-unquote-filename (filename) - (inline-quote - (string-replace "\\\\" "\\" (string-replace "\\\"" "\"" ,filename)))) - -(defun erc-dcc-handle-ctcp-send (proc query nick login host to) - "This is called if a CTCP DCC SEND subcommand is sent to the client. -It extracts the information about the dcc request and adds it to -`erc-dcc-list'." - (unless (eq erc-dcc-send-request 'ignore) - (cond - ((not (erc-current-nick-p to)) - ;; DCC SEND requests must be sent to you, and you alone. - (erc-display-message - nil 'notice proc - 'dcc-request-bogus - ?r "SEND" ?n nick ?u login ?h host)) - ((string-match erc-dcc-ctcp-query-send-regexp query) - (let* ((filename (or (match-string 2 query) - (erc-dcc-unquote-filename (match-string 1 query)))) - (ip (erc-decimal-to-ip (match-string 3 query))) - (port (match-string 4 query)) - (size (match-string 5 query)) - (sub (substring (match-string 6 query) 0 -4)) - (secure (string-search "S" sub)) - (turbo (string-search "T" sub))) - ;; FIXME: a warning really should also be sent - ;; if the ip address != the host the dcc sender is on. - (erc-display-message - nil 'notice proc - 'dcc-send-offered - ?f filename ?n nick ?u login ?h host - ?s (if (string= size "") "unknown" size)) - (and (< (string-to-number port) 1025) - (erc-display-message - nil 'notice proc - 'dcc-privileged-port - ?p port)) - (erc-dcc-list-add - 'GET (format "%s!%s@%s" nick login host) - nil proc - :ip ip :port port :file filename - :size (string-to-number size) - :turbo (and turbo t) - :secure (and secure t)) - (if (and (eq erc-dcc-send-request 'auto) - (erc-dcc-auto-mask-p (format "\"%s!%s@%s\"" nick login host))) - (erc-dcc-get-file (car erc-dcc-list) filename proc)))) - (t - (erc-display-message - nil 'notice proc - 'dcc-malformed - ?n nick ?u login ?h host ?q query))))) - -(defun erc-dcc-auto-mask-p (spec) - "Match SPEC against `erc-dcc-auto-masks'. -SPEC is a full spec of a user in the form \"nick!login@host\", which -is matched against all the regexps in `erc-dcc-auto-masks'. Return -the matching regexp, or nil if none found." - (let ((lst erc-dcc-auto-masks)) - (while (and lst - (not (string-match (car lst) spec))) - (setq lst (cdr lst))) - (and lst (car lst)))) - -(defconst erc-dcc-ctcp-query-chat-regexp - "^DCC CHAT +chat +\\([0-9]+\\) +\\([0-9]+\\)") - -(defcustom erc-dcc-chat-request 'ask - "How to treat incoming DCC Chat requests. -`ask' - Report the Chat request, and wait for the user to manually accept it -`auto' - Automatically accept the request and open a new chat window -`ignore' - Ignore incoming DCC chat requests completely." - :type '(choice (const ask) (const auto) (const ignore))) - -(defun erc-dcc-handle-ctcp-chat (proc query nick login host to) - (unless (eq erc-dcc-chat-request 'ignore) - (cond - (;; DCC CHAT requests must be sent to you, and you alone. - (not (erc-current-nick-p to)) - (erc-display-message - nil '(notice error) proc - 'dcc-request-bogus ?r "CHAT" ?n nick ?u login ?h host)) - ((string-match erc-dcc-ctcp-query-chat-regexp query) - ;; We need to use let* here, since erc-dcc-member might clutter - ;; the match value. - (let* ((ip (erc-decimal-to-ip (match-string 1 query))) - (port (match-string 2 query)) - (elt (erc-dcc-member :nick nick :type 'CHAT))) - ;; FIXME: A warning really should also be sent if the ip - ;; address != the host the dcc sender is on. - (erc-display-message - nil 'notice proc - 'dcc-chat-offered - ?n nick ?u login ?h host ?p port) - (and (< (string-to-number port) 1025) - (erc-display-message - nil 'notice proc - 'dcc-privileged-port ?p port)) - (cond (elt - ;; XXX: why are we updating ip/port on the existing connection? - (setq elt (plist-put (plist-put elt :port port) :ip ip)) - (erc-display-message - nil 'notice proc - 'dcc-chat-discarded ?n nick ?u login ?h host)) - (t - (erc-dcc-list-add - 'CHAT (format "%s!%s@%s" nick login host) - nil proc - :ip ip :port port))) - (if (eq erc-dcc-chat-request 'auto) - (erc-dcc-chat-accept (erc-dcc-member :nick nick :type 'CHAT) - proc)))) - (t - (erc-display-message - nil '(notice error) proc - 'dcc-malformed ?n nick ?u login ?h host ?q query))))) - - -(defvar-local erc-dcc-entry-data nil - "Holds the `erc-dcc-list' entry for this DCC connection.") - -;;; SEND handling - -(defcustom erc-dcc-block-size 1024 - "Block size to use for DCC SEND sessions." - :type 'integer) - -(defcustom erc-dcc-pump-bytes nil - "If an integer, keep sending until that number of bytes are unconfirmed." - :type '(choice (const nil) integer)) - -(define-inline erc-dcc-get-parent (proc) - (inline-quote (plist-get (erc-dcc-member :peer ,proc) :parent))) - -(defun erc-dcc-send-block (proc) - "Send one block of data. -PROC is the process-object of the DCC connection. Returns the number of -bytes sent." - (let* ((elt (erc-dcc-member :peer proc)) - (confirmed-marker (plist-get elt :confirmed)) - (sent-marker (plist-get elt :sent))) - (with-current-buffer (process-buffer proc) - (when erc-dcc-verbose - (erc-display-message - nil 'notice (erc-dcc-get-parent proc) - (format "DCC: Confirmed %d, sent %d, sending block now" - (- confirmed-marker (point-min)) - (- sent-marker (point-min))))) - (let* ((end (min (+ sent-marker erc-dcc-block-size) - (point-max))) - (string (buffer-substring-no-properties sent-marker end))) - (when (< sent-marker end) - (set-marker sent-marker end) - (process-send-string proc string)) - (length string))))) - -(defun erc-dcc-send-filter (proc string) - (let* ((size (erc-unpack-int string)) - (elt (erc-dcc-member :peer proc)) - (parent (plist-get elt :parent)) - (sent-marker (plist-get elt :sent)) - (confirmed-marker (plist-get elt :confirmed))) - (with-current-buffer (process-buffer proc) - (set-marker confirmed-marker (+ (point-min) size)) - (cond - ((and (= confirmed-marker sent-marker) - (= confirmed-marker (point-max))) - (erc-display-message - nil 'notice parent - 'dcc-send-finished - ?n (plist-get elt :nick) - ?f buffer-file-name - ?s (number-to-string (- sent-marker (point-min)))) - (setq erc-dcc-list (delete elt erc-dcc-list)) - (set-buffer-modified-p nil) - (delete-process proc) - (kill-buffer (current-buffer))) - ((<= confirmed-marker sent-marker) - (while (and (< (- sent-marker confirmed-marker) - (or erc-dcc-pump-bytes - erc-dcc-block-size)) - (> (erc-dcc-send-block proc) 0)))) - ((> confirmed-marker sent-marker) - (erc-display-message - nil 'notice parent - (format "DCC: Client confirmed too much (%s vs %s)!" - (marker-position confirmed-marker) - (marker-position sent-marker))) - (set-buffer-modified-p nil) - (delete-process proc) - (kill-buffer (current-buffer))))))) - -(defun erc-dcc-display-send (proc) - (erc-display-message - nil 'notice (erc-dcc-get-parent proc) - (format "DCC: SEND connect from %s" - (format-network-address (process-contact proc :remote))))) - -(defcustom erc-dcc-send-connect-hook - '(erc-dcc-display-send erc-dcc-send-block) - "Hook run when remote end of a DCC SEND offer connected to your listening port." - :type 'hook) - -(defun erc-dcc-nick (plist) - "Extract the nickname portion of the :nick property value in PLIST." - (erc-extract-nick (plist-get plist :nick))) - -(defun erc-dcc-send-sentinel (proc event) - (let* ((elt (erc-dcc-member :peer proc))) - (cond - ((string-match "^open from " event) - (when elt - (let ((buf (marker-buffer (plist-get elt :sent)))) - (with-current-buffer buf - (set-process-buffer proc buf) - (setq erc-dcc-entry-data elt))) - (run-hook-with-args 'erc-dcc-send-connect-hook proc)))))) - -(defun erc-dcc-find-file (file) - (with-current-buffer (generate-new-buffer (file-name-nondirectory file)) - (insert-file-contents-literally file) - (setq buffer-file-name file) - (current-buffer))) - -(defun erc-dcc-file-to-name (file) - (with-temp-buffer - (insert (file-name-nondirectory file)) - (subst-char-in-region (point-min) (point-max) ? ?_ t) - (buffer-string))) - -(defun erc-dcc-send-file (nick file &optional pproc) - "Open socket for incoming connections and send a CTCP send request to the -other client." - (interactive "sNick: \nfFile: ") - (when (null pproc) (if (processp erc-server-process) - (setq pproc erc-server-process) - (error "Can not find parent process"))) - (if (featurep 'make-network-process) - (let* ((buffer (erc-dcc-find-file file)) - (size (buffer-size buffer)) - (start (with-current-buffer buffer - (point-min-marker))) - (sproc (erc-dcc-server "dcc-send" - 'erc-dcc-send-filter - 'erc-dcc-send-sentinel)) - (contact (process-contact sproc))) - (erc-dcc-list-add - 'SEND nick sproc pproc - :file file :size size - :sent start :confirmed (copy-marker start)) - (process-send-string - pproc (format "PRIVMSG %s :\C-aDCC SEND %s %s %d %d\C-a\n" - nick (erc-dcc-file-to-name file) - (erc-ip-to-decimal (or erc-dcc-public-host - (nth 0 contact))) - (nth 1 contact) - size))) - (error "`make-network-process' not supported by your Emacs"))) - -;;; GET handling - -(defcustom erc-dcc-receive-cache (* 1024 512) - "Number of bytes to let the receive buffer grow before flushing it." - :type 'integer) - -(defvar-local erc-dcc-file-name nil) - -(defun erc-dcc-get-file (entry file parent-proc) - "Set up a transfer from the remote client to the local over a TCP connection. -This involves setting up a process filter and a process sentinel, -and making the connection." - (let* ((buffer (generate-new-buffer (file-name-nondirectory file))) - proc) - (with-current-buffer buffer - (fundamental-mode) - (buffer-disable-undo (current-buffer)) - ;; This is necessary to have the buffer saved as-is in GNU - ;; Emacs. - (set-buffer-multibyte nil) - - (setq mode-line-process '(":%s") - buffer-read-only t) - (setq erc-dcc-file-name file) - - ;; Truncate the given file to size 0 before appending to it. - (let ((inhibit-file-name-handlers - (append '(jka-compr-handler image-file-handler) - inhibit-file-name-handlers)) - (inhibit-file-name-operation 'write-region)) - (write-region (point) (point) erc-dcc-file-name nil 'nomessage)) - - (setq erc-server-process parent-proc) - (setq erc-dcc-byte-count 0) - (setq proc - (funcall erc-dcc-connect-function - "dcc-get" buffer - (plist-get entry :ip) - (string-to-number (plist-get entry :port)) - entry)) - (set-process-buffer proc buffer) - (set-process-coding-system proc 'binary 'binary) - (set-buffer-file-coding-system 'binary t) - - (set-process-filter proc #'erc-dcc-get-filter) - (set-process-sentinel proc #'erc-dcc-get-sentinel) - (setq erc-dcc-entry-data (plist-put (plist-put entry :peer proc) - :start-time (erc-current-time)))))) - -(defun erc-dcc-append-contents (buffer _file) - "Append the contents of BUFFER to FILE. -The contents of the BUFFER will then be erased." - (with-current-buffer buffer - (let ((coding-system-for-write 'binary) - (inhibit-read-only t) - (inhibit-file-name-handlers - (append '(jka-compr-handler image-file-handler) - inhibit-file-name-handlers)) - (inhibit-file-name-operation 'write-region)) - (write-region (point-min) (point-max) erc-dcc-file-name t 'nomessage) - (setq erc-dcc-byte-count (+ (buffer-size) erc-dcc-byte-count)) - (erase-buffer)))) - -;; If people really need this, we can convert it into a proper option. - -(defvar erc-dcc--send-final-turbo-ack nil - "Workaround for maverick turbo senders that only require a final ACK. -The only known culprit is WeeChat, with its xfer.network.fast_send -option, which is on by default. Leaving this set to nil and calling -/DCC GET -t works just fine, but WeeChat sees it as a failure even -though the file arrives in its entirety. Setting this to t may -alleviate such problems.") - -(defun erc-dcc-get-filter (proc str) - "This is the process filter for transfers from other clients to this one. -It reads incoming bytes from the network and stores them in the DCC -buffer, and sends back the replies after each block of data per the DCC -protocol spec. Well not really. We write back a reply after each read, -rather than every 1024 byte block, but nobody seems to care." - (with-current-buffer (process-buffer proc) - (let ((inhibit-read-only t) - received-bytes) - (goto-char (point-max)) - (when str - (cl-assert (not (multibyte-string-p str))) - (insert str)) - - (when (> (point-max) erc-dcc-receive-cache) - (erc-dcc-append-contents (current-buffer) erc-dcc-file-name)) - (setq received-bytes (buffer-size)) - (if erc-dcc-byte-count - (setq received-bytes (+ received-bytes erc-dcc-byte-count))) - - (and erc-dcc-verbose - (erc-display-message - nil 'notice erc-server-process - 'dcc-get-bytes-received - ?f (file-name-nondirectory (buffer-name)) - ?b (number-to-string received-bytes))) - (cond - ((and (> (plist-get erc-dcc-entry-data :size) 0) - (> received-bytes (plist-get erc-dcc-entry-data :size))) - (erc-display-message - nil '(notice error) 'active - 'dcc-get-file-too-long - ?f (file-name-nondirectory (buffer-name))) - (delete-process proc)) - ;; Some senders want us to hang up. Only observed w. TSEND. - ((and (plist-get erc-dcc-entry-data :turbo) - (= received-bytes (plist-get erc-dcc-entry-data :size))) - (when erc-dcc--send-final-turbo-ack - (process-send-string proc (erc-pack-int received-bytes))) - (delete-process proc)) - ((not (or (plist-get erc-dcc-entry-data :turbo) - (process-get proc :reportingp))) - (process-put proc :reportingp t) - (process-send-string proc (erc-pack-int received-bytes)) - (process-put proc :reportingp nil)))))) - -(defun erc-dcc-get-sentinel (proc event) - "This is the process sentinel for CTCP DCC SEND connections. -It shuts down the connection and notifies the user that the -transfer is complete." - ;; FIXME, we should look at EVENT, and also check size. - (unless (member event '("connection broken by remote peer\n" - "deleted\n")) - (lwarn 'erc :warning "Unexpected sentinel event %S for %s" - (string-trim-right event) proc)) - (with-current-buffer (process-buffer proc) - (delete-process proc) - (setq erc-dcc-list (delete erc-dcc-entry-data erc-dcc-list)) - (unless (= (point-min) (point-max)) - (erc-dcc-append-contents (current-buffer) erc-dcc-file-name)) - (let ((done (= erc-dcc-byte-count (plist-get erc-dcc-entry-data :size)))) - (erc-display-message - nil (if done 'notice '(notice error)) erc-server-process - (if done 'dcc-get-complete 'dcc-get-failed) - ?v (plist-get erc-dcc-entry-data :size) - ?f erc-dcc-file-name - ?s (number-to-string erc-dcc-byte-count) - ?t (format "%.0f" - (erc-time-diff (plist-get erc-dcc-entry-data :start-time) - nil)))) - (kill-buffer))) - -;;; CHAT handling - -(defcustom erc-dcc-chat-buffer-name-format "DCC-CHAT-%s" - "Format to use for DCC Chat buffer names." - :type 'string) - -(defcustom erc-dcc-chat-mode-hook nil - "Hook calls when `erc-dcc-chat-mode' finished setting up the buffer." - :type 'hook) - -(defcustom erc-dcc-chat-connect-hook nil - "" ; FIXME - :type 'hook) - -(defcustom erc-dcc-chat-exit-hook nil - "" ; FIXME - :type 'hook) - -(defun erc-cmd-CREQ (line &optional _force) - "Set or get the DCC chat request flag. -Possible values are: ask, auto, ignore." - (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line) - (let ((cmd (match-string 1 line))) - (if (stringp cmd) - (erc-display-message - nil 'notice 'active - (format "Set DCC Chat requests to %S" - (setq erc-dcc-chat-request (intern cmd)))) - (erc-display-message nil 'notice 'active - (format "DCC Chat requests are set to %S" - erc-dcc-chat-request))) - t))) - -(defun erc-cmd-SREQ (line &optional _force) - "Set or get the DCC send request flag. -Possible values are: ask, auto, ignore." - (when (string-match "^\\s-*\\(auto\\|ask\\|ignore\\)?$" line) - (let ((cmd (match-string 1 line))) - (if (stringp cmd) - (erc-display-message - nil 'notice 'active - (format "Set DCC Send requests to %S" - (setq erc-dcc-send-request (intern cmd)))) - (erc-display-message nil 'notice 'active - (format "DCC Send requests are set to %S" - erc-dcc-send-request))) - t))) - -(defun pcomplete/erc-mode/CREQ () - (pcomplete-here '("auto" "ask" "ignore"))) -(defalias 'pcomplete/erc-mode/SREQ #'pcomplete/erc-mode/CREQ) - -(defvar erc-dcc-chat-filter-functions '(erc-dcc-chat-parse-output) - "Abnormal hook run after parsing (and maybe inserting) a DCC message. -Each function is called with two arguments: the ERC process and -the unprocessed output.") - -(defvar erc-dcc-chat-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "RET") #'erc-send-current-line) - (define-key map "\t" #'completion-at-point) - map) - "Keymap for `erc-dcc-mode'.") - -(define-derived-mode erc-dcc-chat-mode fundamental-mode "DCC-Chat" - "Major mode for wasting time via DCC chat." - (setq mode-line-process '(":%s") - erc-send-input-line-function #'erc-dcc-chat-send-input-line - erc-default-recipients '(dcc)) - (add-hook 'completion-at-point-functions #'erc-complete-word-at-point nil t)) - -(defun erc-dcc-chat-send-input-line (recipient line &optional _force) - "Send LINE to the remote end. -Argument RECIPIENT should always be the symbol dcc, and force -is ignored." - ;; FIXME: We need to get rid of all force arguments one day! - (if (eq recipient 'dcc) - (process-send-string - (get-buffer-process (current-buffer)) line) - (error "erc-dcc-chat-send-input-line in %s" (current-buffer)))) - -(defun erc-dcc-chat (nick &optional pproc) - "Open a socket for incoming connections, and send a chat request to the -other client." - (interactive "sNick: ") - (when (null pproc) (if (processp erc-server-process) - (setq pproc erc-server-process) - (error "Can not find parent process"))) - (let* ((sproc (erc-dcc-server "dcc-chat-out" - 'erc-dcc-chat-filter - 'erc-dcc-chat-sentinel)) - (contact (process-contact sproc))) - (erc-dcc-list-add 'OCHAT nick sproc pproc) - (process-send-string pproc - (format "PRIVMSG %s :\C-aDCC CHAT chat %s %d\C-a\n" - nick - (erc-ip-to-decimal (nth 0 contact)) (nth 1 contact))))) - -(defvar erc-dcc-from) -(make-variable-buffer-local 'erc-dcc-from) - -(defvar erc-dcc-unprocessed-output) -(make-variable-buffer-local 'erc-dcc-unprocessed-output) - -(defun erc-dcc-chat-setup (entry) - "Setup a DCC chat buffer, returning the buffer." - (let* ((nick (erc-extract-nick (plist-get entry :nick))) - (buffer (generate-new-buffer - (format erc-dcc-chat-buffer-name-format nick))) - (proc (plist-get entry :peer)) - (parent-proc (plist-get entry :parent))) - (erc-setup-buffer buffer) - (with-current-buffer buffer - (erc-dcc-chat-mode) - (setq erc-server-process parent-proc - erc-dcc-from nick - erc-dcc-entry-data entry - erc-dcc-unprocessed-output "" - erc-input-marker (make-marker)) - (erc--initialize-markers (point) nil) - (set-process-buffer proc buffer) - (add-hook 'kill-buffer-hook #'erc-dcc-chat-buffer-killed nil t) - (run-hook-with-args 'erc-dcc-chat-connect-hook proc)) - buffer)) - -(defun erc-dcc-chat-accept (entry parent-proc) - "Accept an incoming DCC connection and open a DCC window." - (let* (;; (nick (erc-extract-nick (plist-get entry :nick))) - proc) ;; buffer - (setq proc - (funcall erc-dcc-connect-function - "dcc-chat" nil - (plist-get entry :ip) - (string-to-number (plist-get entry :port)) - entry)) - ;; XXX: connected, should we kill the ip/port properties? - (setq entry (plist-put entry :peer proc)) - (setq entry (plist-put entry :parent parent-proc)) - (set-process-filter proc #'erc-dcc-chat-filter) - (set-process-sentinel proc #'erc-dcc-chat-sentinel) - ;; (setq buffer - (erc-dcc-chat-setup entry))) ;; ) - -(defun erc-dcc-chat-filter (proc str) - (let ((orig-buffer (current-buffer))) - (unwind-protect - (progn - (set-buffer (process-buffer proc)) - (setq erc-dcc-unprocessed-output - (concat erc-dcc-unprocessed-output str)) - (run-hook-with-args 'erc-dcc-chat-filter-functions - proc erc-dcc-unprocessed-output)) - (set-buffer orig-buffer)))) - -(defun erc-dcc-chat-parse-output (proc str) - (save-match-data - (let ((posn 0) - (erc--msg-prop-overrides `((erc--spkr . ,erc-dcc-from))) - (nick (propertize (erc--speakerize-nick erc-dcc-from) - 'font-lock-face 'erc-nick-default-face)) - line) - (while (string-match "\n" str posn) - (setq line (substring str posn (match-beginning 0))) - (setq posn (match-end 0)) - (erc-display-message - nil nil proc - 'dcc-chat-privmsg ?n nick ?m line)) - (setq erc-dcc-unprocessed-output (substring str posn))))) - -(defun erc-dcc-chat-buffer-killed () - (erc-dcc-chat-close "killed buffer")) - -(defun erc-dcc-chat-close (&optional event) - "Close a DCC chat, removing any associated processes and tidying up -`erc-dcc-list'" - (let ((proc (plist-get erc-dcc-entry-data :peer)) - (evt (or event ""))) - (when proc - (setq erc-dcc-list (delq erc-dcc-entry-data erc-dcc-list)) - (run-hook-with-args 'erc-dcc-chat-exit-hook proc) - (delete-process proc) - (erc-display-message - nil 'notice erc-server-process - 'dcc-chat-ended ?n erc-dcc-from ?t (current-time-string) ?e evt) - (setq erc-dcc-entry-data (plist-put erc-dcc-entry-data :peer nil))))) - -(defun erc-dcc-chat-sentinel (proc event) - (let ((buf (current-buffer)) - (elt (erc-dcc-member :peer proc))) - ;; the sentinel is also notified when the connection is opened, so don't - ;; immediately kill it again - ;(message "buf %s elt %S evt %S" buf elt event) - (unwind-protect - (if (string-match "^open from" event) - (erc-dcc-chat-setup elt) - (erc-dcc-chat-close event)) - (set-buffer buf)))) - -(defun erc-dcc-no-such-nick (proc parsed) - "Detect and handle no-such-nick replies from the IRC server." - (let* ((elt (erc-dcc-member :nick (nth 1 (erc-response.command-args parsed)) - :parent proc)) - (peer (plist-get elt :peer))) - (when (or (and (processp peer) (not (eq (process-status peer) 'open))) - elt) - ;; Since we already created an entry before sending the CTCP - ;; message, we now remove it, if it doesn't point to a process - ;; which is already open. - (setq erc-dcc-list (delq elt erc-dcc-list)) - (if (processp peer) (delete-process peer))) - nil)) - -(provide 'erc-dcc) - -;;; erc-dcc.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-desktop-notifications.el b/lisp/erc/erc-desktop-notifications.el deleted file mode 100644 index 6ef2f0d8ea1..00000000000 --- a/lisp/erc/erc-desktop-notifications.el +++ /dev/null @@ -1,123 +0,0 @@ -;;; erc-desktop-notifications.el --- Send notification on PRIVMSG or mentions -*- lexical-binding:t -*- - -;; Copyright (C) 2012-2025 Free Software Foundation, Inc. - -;; Author: Julien Danjou -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This implements notifications using `notifications-notify' on -;; PRIVMSG received and on public nickname mentions. - -;;; Code: - -(require 'erc) -(require 'xml) -(require 'notifications) -(require 'erc-goodies) -(require 'erc-match) -(require 'dbus) - -(defgroup erc-notifications nil - "Send notifications on PRIVMSG or mentions." - :version "24.3" - :group 'erc) - -(defvar erc-notifications-last-notification nil - "Last notification id.") - -(defcustom erc-notifications-icon nil - "Icon to use for notification." - :type '(choice (const :tag "No icon" nil) file)) - -(defcustom erc-notifications-bus :session - "D-Bus bus to use for notification." - :version "25.1" - :type '(choice (const :tag "Session bus" :session) string)) - -(defvar dbus-debug) ; used in the macroexpansion of dbus-ignore-errors - -(declare-function haiku-notifications-notify "haikuselect.c") -(declare-function android-notifications-notify "androidselect.c") - -(defun erc-notifications-notify (nick msg &optional privp) - "Notify that NICK send some MSG, where PRIVP should be non-nil for PRIVMSGs. -This will replace the last notification sent with this function." - ;; TODO: can we do this without PRIVP? (by "fixing" ERC's not - ;; setting the current buffer to the existing query buffer) - (dbus-ignore-errors - (setq erc-notifications-last-notification - (let* ((channel (if privp (erc-get-buffer nick) (current-buffer))) - (title (format "%s in %s" - (erc-compat--xml-escape-string nick t) - channel)) - (body (erc-compat--xml-escape-string (erc-controls-strip msg) - t))) - (funcall (cond ((featurep 'android) - #'android-notifications-notify) - ((featurep 'haiku) - #'haiku-notifications-notify) - (t #'notifications-notify)) - :bus erc-notifications-bus - :title title - :body body - :replaces-id erc-notifications-last-notification - :app-icon erc-notifications-icon - :actions '("default" "Switch to buffer") - :on-action (lambda (&rest _) - (pop-to-buffer channel))))))) - -(defun erc-notifications-PRIVMSG (_proc parsed) - (let ((nick (car (erc-parse-user (erc-response.sender parsed)))) - (target (car (erc-response.command-args parsed))) - (msg (erc-response.contents parsed))) - (when (and (erc-current-nick-p target) - (not (and (boundp 'erc-track-exclude) - (member nick erc-track-exclude))) - (not (erc-is-message-ctcp-and-not-action-p msg))) - (erc-notifications-notify nick msg t))) - ;; Return nil to continue processing by ERC - nil) - -(defun erc-notifications-notify-on-match (match-type nickuserhost msg) - (when (eq match-type 'current-nick) - (let ((nick (nth 0 (erc-parse-user nickuserhost)))) - (unless (or (string-match-p "^Server:" nick) - (when (boundp 'erc-track-exclude) - (member nick erc-track-exclude))) - (erc-notifications-notify nick msg))))) - -;;;###autoload(autoload 'erc-notifications-mode "erc-desktop-notifications" "" t) -(define-erc-module notifications nil - "Send notifications on private message reception and mentions." - ;; Enable - ((add-hook 'erc-server-PRIVMSG-functions #'erc-notifications-PRIVMSG) - (add-hook 'erc-text-matched-hook #'erc-notifications-notify-on-match)) - ;; Disable - ((remove-hook 'erc-server-PRIVMSG-functions #'erc-notifications-PRIVMSG) - (remove-hook 'erc-text-matched-hook #'erc-notifications-notify-on-match))) - -(provide 'erc-desktop-notifications) - -;;; erc-desktop-notifications.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-ezbounce.el b/lisp/erc/erc-ezbounce.el deleted file mode 100644 index a45484aa54b..00000000000 --- a/lisp/erc/erc-ezbounce.el +++ /dev/null @@ -1,178 +0,0 @@ -;;; erc-ezbounce.el --- Handle EZBounce bouncer commands -*- lexical-binding: t; -*- - -;; Copyright (C) 2002, 2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Andreas Fuchs -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;;; Code: - -(require 'erc) - -(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." - :type 'regexp) - -(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)) - ...)" - :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 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-local erc-ezb-session-list '() - "List of detached EZBounce sessions.") - -(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 "^\\([^ \n]+\\) +\\([^ \n]+\\) +\\([^ \n]+\\) +\\([^ \n]+\\)$" 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) - -;;; erc-ezbounce.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el deleted file mode 100644 index 6b7dcec5eda..00000000000 --- a/lisp/erc/erc-fill.el +++ /dev/null @@ -1,932 +0,0 @@ -;;; erc-fill.el --- Filling IRC messages in various ways -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Andreas Fuchs -;; Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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. - -;; TODO: redo `erc-fill-wrap-nudge' using transient after ERC drops -;; support for Emacs 27. - -;;; 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) -(define-erc-module fill nil - "Manage filling in ERC buffers. -ERC fill mode is a global minor mode. When enabled, messages in -channel buffers are filled. See also `erc-fill-wrap-mode'." - ((add-hook 'erc-insert-modify-hook #'erc-fill 60) - (add-hook 'erc-send-modify-hook #'erc-fill 60)) - ((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." - :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: - - this is a very very very long message with no - meaning at all - -Variable Filling with an `erc-fill-prefix' of four spaces: - - this is a very very very long message with no - meaning at all - -Static Filling with `erc-fill-static-center' of 27: - - foo bar baz - foo bar baz quuuuux - 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. - -A third style resembles static filling but \"wraps\" instead of -fills, thanks to `visual-line-mode' mode, which ERC automatically -enables when this option is `erc-fill-wrap' or when the module -`fill-wrap' is active. Use `erc-fill-static-center' to specify -an initial \"prefix\" width and `erc-fill-wrap-margin-width' -instead of `erc-fill-column' for influencing initial message -width. For adjusting these during a session, see the commands -`erc-fill-wrap-nudge' and `erc-fill-wrap-refill-buffer'. Read -more about this style in the doc string for `erc-fill-wrap-mode'." - :type '(choice (const :tag "Variable Filling" erc-fill-variable) - (const :tag "Static Filling" erc-fill-static) - (const :tag "Dynamic word-wrap" erc-fill-wrap) - function)) - -(defcustom erc-fill-static-center 27 - "Number of columns to \"outdent\" the first line of a message. -During early message handing, ERC prepends a span of -non-whitespace characters to every message, such as a bracketed -\"\" or an `erc-notice-prefix'. The -`erc-fill-function' variants `erc-fill-static' and -`erc-fill-wrap' look to this option to determine the amount of -padding to apply to that portion until the filled (or wrapped) -message content aligns with the indicated column. See also -https://en.wikipedia.org/wiki/Hanging_indent." - :type 'integer) - -(defcustom erc-fill-variable-maximum-indentation 17 - "Don't indent a line after a long nick more than this many characters. -Set to nil to disable." - :type '(choice (const :tag "Disable" nil) - integer)) - -(defcustom erc-fill-column 78 - "The column at which a filled paragraph is broken." - :type 'integer) - -(defcustom erc-fill-wrap-margin-width nil - "Starting width in columns of dedicated stamp margin. -When nil, ERC normally pretends its value is one column greater -than the `string-width' of the formatted `erc-timestamp-format'. -However, when `erc-fill-wrap-margin-side' is `left' or -\"resolves\" to `left', ERC uses the width of the prompt if it's -wider on MOTD's end, which really only matters when `erc-prompt' -is a function." - :package-version '(ERC . "5.6") - :type '(choice (const nil) integer)) - -(defcustom erc-fill-wrap-margin-side nil - "Margin side to use with `erc-fill-wrap-mode'. -A value of nil means ERC should decide based on the value of -`erc-insert-timestamp-function', which does not work for -user-defined functions." - :package-version '(ERC . "5.6") - :type '(choice (const nil) (const left) (const right))) - -(defcustom erc-fill-wrap-align-prompt nil - "Whether to align the prompt at the common `wrap-prefix'." - :package-version '(ERC . "5.6") - :type 'boolean) - -(defvar erc-fill-line-spacing nil - "Extra space between messages on graphical displays. -Its value should probably be larger than that of the variable -`line-spacing', if non-nil. When unsure, start with 1.0. Note -that as of ERC 5.6, this feature doesn't combine well with the -`scrolltobottom' module, which is de facto required when using -the `fill-wrap' filling style. Users should therefore regard -this variable as experimental for the time being.") - -(defvar-local erc-fill--function nil - "Internal copy of `erc-fill-function'. -Takes precedence over the latter when non-nil.") - -;;;###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 (or erc-fill--function erc-fill-function) - ;; skip initial empty lines - (goto-char (point-min)) - ;; Note the following search pattern was altered in 5.6 to adapt - ;; to a change in Emacs regexp behavior that turned out to be a - ;; regression (which has since been fixed). The patterns appear - ;; to be equivalent in practice, so this was left as is (wasn't - ;; reverted) to avoid additional git-blame(1)-related churn. - (while (and (looking-at (rx bol (* (in " \t")) eol)) - (zerop (forward-line 1)))) - (unless (eobp) - (save-restriction - (narrow-to-region (point) (point-max)) - (funcall (or erc-fill--function erc-fill-function)) - (when-let ((erc-fill-line-spacing) - (p (point-min))) - (widen) - (when (or (erc--check-msg-prop 'erc--spkr) - (save-excursion - (forward-line -1) - (erc--get-inserted-msg-prop 'erc--spkr))) - (put-text-property (1- p) p - 'line-spacing erc-fill-line-spacing)))))))) - -(defun erc-fill-static () - "Fills a text such that messages start at column `erc-fill-static-center'." - (save-restriction - (goto-char (point-min)) - (when-let (((looking-at "^\\(\\S-+\\)")) - ((not (erc--check-msg-prop 'erc--msg 'datestamp))) - (nick (match-string 1))) - (progn - (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))) - -(defvar-local erc-fill--wrap-value nil) -(defvar-local erc-fill--wrap-visual-keys nil) - -(defvar erc-fill-wrap-use-pixels t - "Whether to calculate padding in pixels when possible. -A value of nil means ERC should use columns, which may happen -regardless, depending on the Emacs version. This option only -matters when `erc-fill-wrap-mode' is enabled.") - -(defcustom erc-fill-wrap-visual-keys 'non-input - "Whether to retain keys defined by `visual-line-mode'. -A value of t tells ERC to use movement commands defined by -`visual-line-mode' everywhere in an ERC buffer along with visual -editing commands in the input area. A value of nil means to -never do so. A value of `non-input' tells ERC to act like the -value is nil in the input area and t elsewhere. See related -option `erc-fill-wrap-force-screen-line-movement' for behavior -involving `next-line' and `previous-line'." - :package-version '(ERC . "5.6") - :type '(choice (const nil) (const t) (const non-input))) - -(defcustom erc-fill-wrap-force-screen-line-movement '(non-input) - "Exceptions for vertical movement by logical line. -Including a symbol known to `erc-fill-wrap-visual-keys' in this -set tells `next-line' and `previous-line' to move vertically by -screen line even if the current `erc-fill-wrap-visual-keys' value -would normally do otherwise. For example, setting this to -\\='(nil non-input) disables logical-line movement regardless of -the value of `erc-fill-wrap-visual-keys'." - :package-version '(ERC . "5.6") - :type '(set (const nil) (const non-input))) - -(defcustom erc-fill-wrap-merge t - "Whether to consolidate consecutive messages from the same speaker. -When non-nil, ERC omits redundant speaker labels for subsequent -messages less than a day apart. To help distinguish between -merged messages, see option `erc-fill-wrap-merge-indicator'." - :package-version '(ERC . "5.6") - :type 'boolean) - -(defface erc-fill-wrap-merge-indicator-face - '((((min-colors 88) (background light)) :foreground "Gray") - (((min-colors 16) (background light)) :foreground "LightGray") - (((min-colors 16) (background dark)) :foreground "DimGray") - (t :inherit shadow)) - "ERC `fill-wrap' merge-indicator face." - :group 'erc-faces) - -(defcustom erc-fill-wrap-merge-indicator nil - "Indicator to help distinguish between merged messages. -Only matters when the option `erc-fill-wrap-merge' is enabled. -If the value is a cons of a character, like ?>, and a valid face, -ERC generates a replacement for the speaker's name tag. The -first two presets replace a continued speaker's name with a -bullet-like character in `shadow' face. - -Note that as of ERC 5.6, this option is still experimental, and -changing its value mid-session is not yet supported (though, if -you must, make sure to run \\[erc-fill-wrap-refill-buffer] -afterward). Also note that users on versions of Emacs older than -29.2 may experience a \"glitching\" effect when point resides on -a \"merged\" message occupying the first or last line in a -window. If that happens, try replacing `top' with the integer 1 -in the option `recenter-positions' while also maybe adjusting -`scroll-margin' and/or `scroll-preserve-screen-position' to avoid -\"dragging\" point when issuing a `scroll-up' or `scroll-down' -command." - :package-version '(ERC . "5.6") - :type - '(choice (const nil) - (const :tag "Leading MIDDLE DOT (U+00B7) as speaker" - (#xb7 . erc-fill-wrap-merge-indicator-face)) - (const :tag "Leading MIDDLE DOT (U+00B7) sans gap" - #("\u00b7" - 0 1 (font-lock-face erc-fill-wrap-merge-indicator-face))) - (const :tag "Leading RIGHT-ANGLE BRACKET (>) as speaker" - (?> . erc-fill-wrap-merge-indicator-face)) - (string :tag "User-provided string (advanced)") - (cons :tag "User-provided character-face pairing" character face))) - -(defun erc-fill--wrap-move (normal-cmd visual-cmd &rest args) - (apply (pcase erc-fill--wrap-visual-keys - ('non-input - (if (>= (point) erc-input-marker) normal-cmd visual-cmd)) - ('t visual-cmd) - (_ normal-cmd)) - args)) - -(defun erc-fill--wrap-kill-line (arg) - "Defer to `kill-line' or `kill-visual-line'." - (interactive "P") - ;; ERC buffers are read-only outside of the input area, but we run - ;; `kill-line' anyway so that users can see the error. - (erc-fill--wrap-move #'kill-line #'kill-visual-line arg)) - -(defun erc-fill--wrap-escape-hidden-speaker (&optional old-point) - "Move to start of message text when left of speaker. -Basically mimic what `move-beginning-of-line' does with invisible text. -Stay put if OLD-POINT lies within hidden region." - (when-let ((erc-fill-wrap-merge) - (prop (get-text-property (point) 'erc-fill--wrap-merge)) - ((or (member prop '("" t)) - (eq 'margin (car-safe (car-safe prop))))) - (end (text-property-not-all (point) (pos-eol) - 'erc-fill--wrap-merge prop)) - ((or (null old-point) (>= old-point end)))) - (goto-char end))) - -(defun erc-fill--wrap-beginning-of-line (arg) - "Defer to `move-beginning-of-line' or `beginning-of-visual-line'." - (interactive "^p") - (let ((opoint (point))) - (let ((inhibit-field-text-motion t)) - (erc-fill--wrap-move #'move-beginning-of-line - #'beginning-of-visual-line arg)) - (if (get-text-property (point) 'erc-prompt) - (goto-char erc-input-marker) - (when erc-fill-wrap-merge - (erc-fill--wrap-escape-hidden-speaker opoint))))) - -(defun erc-fill--wrap-previous-line (&optional arg try-vscroll) - "Move to ARGth previous logical or screen line." - (interactive "^p\np") - ;; Return value seems undefined but preserve anyway just in case. - (prog1 - (let ((visp (memq erc-fill--wrap-visual-keys - erc-fill-wrap-force-screen-line-movement))) - (erc-fill--wrap-move (if visp #'previous-line #'previous-logical-line) - #'previous-line - arg try-vscroll)) - (when erc-fill-wrap-merge - (erc-fill--wrap-escape-hidden-speaker)))) - -(defun erc-fill--wrap-next-line (&optional arg try-vscroll) - "Move to ARGth next logical or screen line." - (interactive "^p\np") - (let ((visp (memq erc-fill--wrap-visual-keys - erc-fill-wrap-force-screen-line-movement))) - (erc-fill--wrap-move (if visp #'next-line #'next-logical-line) - #'next-line - arg try-vscroll) - (when erc-fill-wrap-merge - (erc-fill--wrap-escape-hidden-speaker)))) - -(defun erc-fill--wrap-end-of-line (arg) - "Defer to `move-end-of-line' or `end-of-visual-line'." - (interactive "^p") - (erc-fill--wrap-move #'move-end-of-line #'end-of-visual-line arg)) - -(defun erc-fill-wrap-cycle-visual-movement (arg) - "Cycle through `erc-fill-wrap-visual-keys' styles ARG times. -Go from nil to t to `non-input' and back around, but set internal -state instead of mutating `erc-fill-wrap-visual-keys'. When ARG -is 0, reset to value of `erc-fill-wrap-visual-keys'." - (interactive "^p") - (when (zerop arg) - (setq erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys)) - (while (not (zerop arg)) - (cl-incf arg (- (abs arg))) - (setq erc-fill--wrap-visual-keys (pcase erc-fill--wrap-visual-keys - ('nil t) - ('t 'non-input) - ('non-input nil)))) - (message "erc-fill-wrap movement: %S" erc-fill--wrap-visual-keys)) - -(defun erc-fill-wrap-toggle-truncate-lines (arg) - "Toggle `truncate-lines' and maybe reinstate `visual-line-mode'." - (interactive "P") - (let ((wantp (if arg - (natnump (prefix-numeric-value arg)) - (not truncate-lines))) - (buffer (current-buffer))) - (if wantp - (setq truncate-lines t) - (walk-windows (lambda (window) - (when (eq buffer (window-buffer window)) - (set-window-hscroll window 0))) - nil t) - (visual-line-mode +1))) - (force-mode-line-update)) - -(defvar-keymap erc-fill-wrap-mode-map ; Compat 29 - :doc "Keymap for ERC's `fill-wrap' module." - :parent visual-line-mode-map - " " #'erc-fill--wrap-kill-line - " " #'erc-fill--wrap-end-of-line - " " #'erc-fill--wrap-beginning-of-line - " " #'erc-fill-wrap-toggle-truncate-lines - " " #'erc-fill--wrap-next-line - " " #'erc-fill--wrap-previous-line - ;; Not sure if this is problematic because `erc-bol' takes no args. - " " #'erc-fill--wrap-beginning-of-line) - -(defvar erc-button-mode) -(defvar erc-scrolltobottom-mode) -(defvar erc-legacy-invisible-bounds-p) - -(defvar erc-fill--wrap-scrolltobottom-exempt-p nil) - -(defun erc-fill--wrap-ensure-dependencies () - (with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p)) - (when erc-legacy-invisible-bounds-p - (erc--warn-once-before-connect 'erc-fill-wrap-mode - "Module `fill-wrap' is incompatible with the obsolete compatibility" - " flag `erc-legacy-invisible-bounds-p'. Disabling locally in %s." - (current-buffer)) - (setq-local erc-legacy-invisible-bounds-p nil))) - (let (missing-deps) - (unless erc-fill-mode - (push 'fill missing-deps) - (erc-fill-mode +1)) - (unless (or erc-scrolltobottom-mode erc-fill--wrap-scrolltobottom-exempt-p - (memq 'scrolltobottom erc-modules)) - (push 'scrolltobottom missing-deps) - (erc-scrolltobottom-mode +1)) - (when erc-fill-wrap-merge - (require 'erc-button) - (unless erc-button-mode - (push 'button missing-deps) - (erc-button-mode +1)) - (require 'erc-stamp) - (unless erc-stamp-mode - (push 'stamp missing-deps) - (erc-stamp-mode +1))) - (when missing-deps - (erc--warn-once-before-connect 'erc-fill-wrap-mode - "Enabling missing global modules %s needed by local" - " module `fill-wrap'. This will impact \C-]all\C-] ERC" - " sessions. Add them to `erc-modules' to avoid this" - " warning. See Info:\"(erc) Modules\" for more." - (mapcar (lambda (s) (format "`%s'" s)) missing-deps))))) - -(defun erc-fill--wrap-massage-legacy-indicator-type () - "Migrate obsolete 5.6-git `erc-fill-wrap-merge-indicator' format." - (pcase erc-fill-wrap-merge-indicator - (`(post . ,_) - (erc--warn-once-before-connect 'erc-fill-wrap-mode - "The option `erc-fill-wrap-merge-indicator' has changed. Unfortunately," - " the `post' variant and related presets are no longer available." - " Setting to nil for the current session. Apologies for the disruption." - (setq erc-fill-wrap-merge-indicator nil))) - (`(pre . ,(and (pred stringp) string)) - (erc--warn-once-before-connect 'erc-fill-wrap-mode - "The format of option `erc-fill-wrap-merge-indicator' has changed" - " from a cons of (pre . STRING) to STRING. Please update your settings." - " Changing temporarily to \"" string "\" for the current session.") - (setq erc-fill-wrap-merge-indicator string)) - (`(pre ,(and (pred characterp) char) ,face) - (erc--warn-once-before-connect 'erc-fill-wrap-mode - "The format of option `erc-fill-wrap-merge-indicator' has changed" - " from (pre CHAR FACE) to a cons of (CHAR . FACE). Please update" - " when possible. Changing temporarily to %S for the current session." - (setq erc-fill-wrap-merge-indicator (cons char face)))))) - -;;;###autoload(put 'fill-wrap 'erc--feature 'erc-fill) -(define-erc-module fill-wrap nil - "Fill style leveraging `visual-line-mode'. - -This module displays nicks overhanging leftward to a common -offset, as determined by the option `erc-fill-static-center'. It -also \"wraps\" messages at a common width, as determined by the -option `erc-fill-wrap-margin-width'. To use it, either include -`fill-wrap' in `erc-modules' or set `erc-fill-function' to -`erc-fill-wrap'. - -Once enabled, use \\[erc-fill-wrap-nudge] to adjust the width of -the indent and the stamp margin. For cycling between -logical- and screen-line oriented command movement, see -\\[erc-fill-wrap-toggle-truncate-lines]. Similarly, use -\\[erc-fill-wrap-refill-buffer] to fix alignment problems after -running certain commands, like `text-scale-adjust'. Also see -related stylistic options `erc-fill-wrap-merge' and -`erc-fill-wrap-merge-indicator'. (Hint: in narrow windows, try -setting `erc-fill-static-center' to 1 and choosing \"Leading -MIDDLE DOT sans gap\" for `erc-fill-wrap-merge-indicator'.) - -This module imposes various restrictions on the appearance of -timestamps. Most notably, it insists on displaying them in the -margins. Users preferring left-sided stamps may notice that ERC -also displays the prompt in the left margin, possibly truncating -or padding it to constrain it to the margin's width. -Additionally, this module assumes that users providing their own -`erc-insert-timestamp-function' have also customized the option -`erc-fill-wrap-margin-side' to an explicit side. When stamps -appear in the right margin, which they do by default, users may -find that ERC actually appends them to copy-as-killed messages. -This normally poses at most a minor inconvenience. Users of the -`log' module wanting to avoid this effect in logs should see -`erc-stamp-prefix-log-filter', which strips trailing stamps from -logged messages and instead prepends them to every line. - -A so-called \"local\" module, `fill-wrap' depends on the global -modules `fill', `stamp', `button', and `scrolltobottom'. It -activates them as needed when initializing and leaves them -enabled when shutting down. To opt out of `scrolltobottom' -specifically, disable its minor mode, `erc-scrolltobottom-mode', -via `erc-fill-wrap-mode-hook'." - ((erc-fill--wrap-ensure-dependencies) - (when erc-fill-wrap-merge-indicator - (erc-fill--wrap-massage-legacy-indicator-type)) - (erc--restore-initialize-priors erc-fill-wrap-mode - erc-fill--wrap-visual-keys erc-fill-wrap-visual-keys - erc-fill--wrap-value erc-fill-static-center - erc-stamp--margin-width erc-fill-wrap-margin-width - left-margin-width left-margin-width - right-margin-width right-margin-width) - (setq erc-stamp--margin-left-p - (or (eq erc-fill-wrap-margin-side 'left) - (eq (default-value 'erc-insert-timestamp-function) - #'erc-insert-timestamp-left))) - (when erc-fill-wrap-align-prompt - (add-hook 'erc--refresh-prompt-hook - #'erc-fill--wrap-indent-prompt nil t)) - (when erc-stamp--margin-left-p - (if erc-fill-wrap-align-prompt - (setq erc-stamp--skip-left-margin-prompt-p t) - (setq erc--inhibit-prompt-display-property-p t))) - (add-hook 'erc-stamp--insert-date-hook - #'erc-fill--wrap-unmerge-on-date-stamp 20 t) - (setq erc-fill--function #'erc-fill-wrap) - (when erc-fill-wrap-merge - (add-hook 'erc-button--prev-next-predicate-functions - #'erc-fill--wrap-merged-button-p nil t)) - (add-function :after (local 'erc--clear-function) - #'erc-fill--wrap-massage-initial-message-post-clear - '((depth . 50))) - (erc-stamp--display-margin-mode +1) - (visual-line-mode +1)) - ((visual-line-mode -1) - (erc-stamp--display-margin-mode -1) - (kill-local-variable 'erc-fill--wrap-value) - (kill-local-variable 'erc-fill--function) - (kill-local-variable 'erc-fill--wrap-visual-keys) - (kill-local-variable 'erc-fill--wrap-last-msg) - (kill-local-variable 'erc--inhibit-prompt-display-property-p) - (kill-local-variable 'erc-fill--wrap-merge-indicator-pre) - (remove-function (local 'erc--clear-function) - #'erc-fill--wrap-massage-initial-message-post-clear) - (remove-hook 'erc--refresh-prompt-hook - #'erc-fill--wrap-indent-prompt t) - (remove-hook 'erc-button--prev-next-predicate-functions - #'erc-fill--wrap-merged-button-p t) - (remove-hook 'erc-stamp--insert-date-hook - #'erc-fill--wrap-unmerge-on-date-stamp t)) - localp) - -(defvar-local erc-fill--wrap-length-function nil - "Function to determine length of overhanging characters. -It should return an EXPR as defined by the Info node `(elisp) -Pixel Specification'. This value should represent the width of -the overhang with all faces applied, including any enclosing -brackets (which are not normally fontified) and a trailing space. -It can also return nil to tell ERC to fall back to the default -behavior of taking the length from the first \"word\". This -variable can be converted to a public one if needed by third -parties.") - -(defvar-local erc-fill--wrap-last-msg nil "Marker for merging speakers.") -(defvar erc-fill--wrap-max-lull (* 24 60 60) "Max secs for merging speakers.") - -(defun erc-fill--wrap-continued-message-p () - "Return non-nil when the current speaker hasn't changed. -But only if the `erc--msg' text property also hasn't. That is, -indicate whether the chat message just inserted is from the same -person as the prior one and is formatted in the same manner. As -a side effect, advance `erc-fill--wrap-last-msg' unless the -message has been marked `erc--ephemeral'." - (and-let* - (((not (erc--check-msg-prop 'erc--ephemeral))) - ;; Always set/move `erc-fill--wrap-last-msg' from here on down. - (m (or (and erc-fill--wrap-last-msg - (prog1 (marker-position erc-fill--wrap-last-msg) - (set-marker erc-fill--wrap-last-msg (point-min)))) - (ignore (setq erc-fill--wrap-last-msg (point-min-marker))))) - ((>= (point) 4)) ; skip the first message - (props (save-restriction - (widen) - (and-let* ((speaker (get-text-property m 'erc--spkr)) - (type (get-text-property m 'erc--msg)) - ((not (invisible-p m)))) - (list (get-text-property m 'erc--ts) type speaker)))) - (ts (nth 0 props)) - (type (nth 1 props)) - (speaker (nth 2 props)) - ((not (time-less-p (erc-stamp--current-time) ts))) - ((time-less-p (time-subtract (erc-stamp--current-time) ts) - erc-fill--wrap-max-lull)) - ((erc--check-msg-prop 'erc--msg type)) - ((erc-nick-equal-p speaker (erc--check-msg-prop 'erc--spkr)))))) - -(defun erc-fill--wrap-measure (beg end) - "Return display spec width for inserted region between BEG and END. -Ignore any `invisible' props that may be present when figuring. -Expect the target region to be free of `line-prefix' and -`wrap-prefix' properties, and expect `display-line-numbers-mode' -to be disabled." - (if (fboundp 'buffer-text-pixel-size) - ;; `buffer-text-pixel-size' can move point! - (save-excursion - (save-restriction - (narrow-to-region beg end) - (let* ((buffer-invisibility-spec) - (rv (car (buffer-text-pixel-size)))) - (if erc-fill-wrap-use-pixels - (if (zerop rv) 0 (list rv)) - (/ rv (frame-char-width)))))) - (- end beg))) - -;; An escape hatch for third-party code expecting speakers of ACTION -;; messages to be exempt from `line-prefix'. This could be converted -;; into a user option if users feel similarly. -(defvar erc-fill--wrap-action-dedent-p t - "Whether to dedent speakers in CTCP \"ACTION\" lines.") - -(defvar-local erc-fill--wrap-merge-indicator-pre nil) - -(defun erc-fill--wrap-insert-merged-pre () - "Add `display' text property to speaker. -Also cover region with text prop `erc-fill--wrap-merge' set to t." - (if erc-fill--wrap-merge-indicator-pre - (progn - (add-text-properties (point-min) (point) - (list 'display - (car erc-fill--wrap-merge-indicator-pre) - 'erc-fill--wrap-merge t)) - (cdr erc-fill--wrap-merge-indicator-pre)) - (let* ((option erc-fill-wrap-merge-indicator) - (s (if (stringp option) - (concat option) - (concat (propertize (string (car option)) - 'font-lock-face (cdr option)) - " ")))) - (add-text-properties (point-min) (point) - (list 'display s 'erc-fill--wrap-merge t)) - (cdr (setq erc-fill--wrap-merge-indicator-pre - (cons s (erc-fill--wrap-measure (point-min) (point)))))))) - -(defvar erc-fill--wrap-continued-predicate #'erc-fill--wrap-continued-message-p - "Function called with no args to detect a continued speaker.") - -(defvar erc-fill--wrap-rejigger-last-message nil - "Temporary working instance of `erc-fill--wrap-last-msg'.") - -(defun erc-fill--wrap-unmerge-on-date-stamp () - "Re-wrap message on date-stamp insertion." - (when (and erc-fill-wrap-merge (null erc-fill--wrap-rejigger-last-message)) - (let ((next-beg (point-max))) - (save-restriction - (widen) - (when-let (((get-text-property next-beg 'erc-fill--wrap-merge)) - (end (erc--get-inserted-msg-bounds next-beg)) - (beg (pop end)) - (erc-fill--wrap-continued-predicate #'ignore)) - (erc-fill--wrap-rejigger-region (1- beg) (1+ end) nil 'repairp)))))) - -(defun erc-fill--wrap-massage-initial-message-post-clear (beg end) - "Maybe reveal hidden speaker or add stamp on initial message after END." - (if erc-stamp--date-mode - (erc-stamp--redo-right-stamp-post-clear beg end) - ;; With other non-date stamp-insertion functions, remove hidden - ;; speaker continuation on first spoken message in buffer. - (when-let (((< end (1- erc-insert-marker))) - (next (text-property-not-all end (min erc-insert-marker - (+ 4096 end)) - 'erc--msg nil)) - (bounds (erc--get-inserted-msg-bounds next)) - (found (text-property-not-all (car bounds) (cdr bounds) - 'erc-fill--wrap-merge nil)) - (erc-fill--wrap-continued-predicate #'ignore)) - (erc-fill--wrap-rejigger-region (max (1- (car bounds)) (point-min)) - (min (1+ (cdr bounds)) erc-insert-marker) - nil 'repairp)))) - -(defun erc-fill-wrap () - "Use text props to mimic the effect of `erc-fill-static'. -See `erc-fill-wrap-mode' for details." - (unless erc-fill-wrap-mode - (erc-fill-wrap-mode +1)) - (save-excursion - (goto-char (point-min)) - (let ((len (or (and erc-fill--wrap-length-function - (funcall erc-fill--wrap-length-function)) - (and-let* ((msg-prop (erc--check-msg-prop 'erc--msg)) - ((not (eq msg-prop 'unknown)))) - (when-let ((e (erc--get-speaker-bounds)) - (b (pop e)) - ((or erc-fill--wrap-action-dedent-p - (not (erc--check-msg-prop 'erc--ctcp - 'ACTION))))) - (goto-char e)) - (skip-syntax-forward "^-") - (forward-char) - (cond ((eq msg-prop 'datestamp) - (when erc-fill--wrap-rejigger-last-message - (set-marker erc-fill--wrap-last-msg (point-min))) - (save-excursion - (goto-char (point-max)) - (skip-chars-backward "\n") - (let ((beg (pos-bol))) - (insert " ") - (prog1 (erc-fill--wrap-measure beg (point)) - (delete-region (1- (point)) (point)))))) - ((and erc-fill-wrap-merge - (funcall erc-fill--wrap-continued-predicate)) - (add-text-properties - (point-min) (point) - '(display "" erc-fill--wrap-merge "")) - (if erc-fill-wrap-merge-indicator - (erc-fill--wrap-insert-merged-pre) - 0)) - (t - (erc-fill--wrap-measure (point-min) (point)))))))) - (add-text-properties - (point-min) (1- (point-max)) ; exclude "\n" - `( line-prefix (space :width ,(if len - `(- erc-fill--wrap-value ,len) - 'erc-fill--wrap-value)) - wrap-prefix (space :width erc-fill--wrap-value)))))) - -(defun erc-fill--wrap-indent-prompt () - "Recompute the `line-prefix' of the prompt." - ;; Clear an existing `line-prefix' before measuring (bug#64971). - (remove-text-properties erc-insert-marker erc-input-marker - '(line-prefix nil wrap-prefix nil)) - ;; Restoring window configuration seems to prevent unwanted - ;; recentering reminiscent of `scrolltobottom'-related woes. - (let ((c (and (get-buffer-window) (current-window-configuration))) - (len (erc-fill--wrap-measure erc-insert-marker erc-input-marker))) - (when c - (set-window-configuration c)) - (put-text-property erc-insert-marker erc-input-marker - 'line-prefix - `(space :width (- erc-fill--wrap-value ,len))))) - -(defun erc-fill--wrap-rejigger-region (start finish on-next repairp) - "Recalculate `line-prefix' from START to FINISH. -After refilling each message, call ON-NEXT with no args. But -stash and restore `erc-fill--wrap-last-msg' before doing so, in -case this module's insert hooks run by way of the process filter. -With REPAIRP, destructively fill gaps and re-merge speakers." - (goto-char start) - (setq erc-fill--wrap-merge-indicator-pre nil) - (let ((erc-fill--wrap-rejigger-last-message - erc-fill--wrap-rejigger-last-message)) - (while-let - (((< (point) finish)) - (beg (if (get-text-property (point) 'line-prefix) - (point) - (next-single-property-change (point) 'line-prefix))) - (val (get-text-property beg 'line-prefix)) - (end (text-property-not-all beg finish 'line-prefix val))) - ;; If this is a left-side stamp on its own line. - (remove-text-properties beg (1+ end) '(line-prefix nil wrap-prefix nil)) - (when-let ((repairp) - (dbeg (text-property-not-all beg end - 'erc-fill--wrap-merge nil)) - ((get-text-property (1+ dbeg) 'erc--speaker)) - (dval (get-text-property dbeg 'erc-fill--wrap-merge))) - (remove-list-of-text-properties - dbeg (text-property-not-all dbeg end 'erc-fill--wrap-merge dval) - '(display erc-fill--wrap-merge))) - ;; This "should" work w/o `front-sticky' and `rear-nonsticky'. - (let* ((pos (if-let (((eq 'erc-timestamp (field-at-pos beg))) - (b (field-beginning beg)) - ((eq 'datestamp (get-text-property b 'erc--msg)))) - b - beg)) - (erc--msg-props (map-into (text-properties-at pos) 'hash-table)) - (erc-stamp--current-time (gethash 'erc--ts erc--msg-props))) - (save-restriction - (narrow-to-region beg (1+ end)) - (let ((erc-fill--wrap-last-msg erc-fill--wrap-rejigger-last-message)) - (erc-fill-wrap) - (setq erc-fill--wrap-rejigger-last-message - erc-fill--wrap-last-msg)))) - (when on-next - (funcall on-next)) - ;; Skip to end of message upon encountering accidental gaps - ;; introduced by third parties (or bugs). - (if-let (((/= ?\n (char-after end))) - (next (erc--get-inserted-msg-end beg))) - (progn - (cl-assert (= ?\n (char-after next))) - (when repairp ; eol <= next - (put-text-property end (pos-eol) 'line-prefix val)) - (goto-char next)) - (goto-char end))))) - -;; FIXME restore rough window position after finishing. -(defun erc-fill-wrap-refill-buffer (repair) - "Recalculate all `fill-wrap' prefixes in the current buffer. -With REPAIR, attempt to refresh \"speaker merges\", which may be -necessary after revealing previously hidden text with commands -like `erc-match-toggle-hidden-fools'." - (interactive "P") - (unless erc-fill-wrap-mode - (user-error "Module `fill-wrap' not active in current buffer")) - (save-excursion - (with-silent-modifications - (let* ((rep (make-progress-reporter - "Rewrap" 0 (line-number-at-pos erc-insert-marker) 1)) - (seen 0) - (callback (lambda () - (progress-reporter-update rep (cl-incf seen)) - (accept-process-output nil 0.000001)))) - (erc-fill--wrap-rejigger-region (point-min) erc-insert-marker - callback repair) - (progress-reporter-done rep))))) - -(defun erc-fill--wrap-merged-button-p (point) - (get-text-property point 'erc-fill--wrap-merge)) - -(defun erc-fill--wrap-nudge (arg) - (when (zerop arg) - (setq arg (- erc-fill-static-center erc-fill--wrap-value))) - (cl-incf erc-fill--wrap-value arg) - arg) - -(defun erc-fill-wrap-nudge (arg) - "Adjust `erc-fill-wrap' by ARG columns. -Offer to repeat command in a manner similar to -`text-scale-adjust'. - - \\`=' Increase indentation by one column - \\`-' Decrease indentation by one column - \\`0' Reset indentation to the default - \\`+' Shift margin boundary rightward by one column - \\`_' Shift margin boundary leftward by one column - \\`)' Reset the right margin to the default - -Note that misalignment may occur when messages contain -decorations applied by third-party modules." - (interactive "p") - (unless erc-fill--wrap-value - (cl-assert (not erc-fill-wrap-mode)) - (user-error "Minor mode `erc-fill-wrap-mode' disabled")) - (unless (get-buffer-window) - (user-error "Command called in an undisplayed buffer")) - (let* ((total (erc-fill--wrap-nudge arg)) - (leftp erc-stamp--margin-left-p) - ;; Anchor current line vertically. - (line (count-screen-lines (window-start) (window-point)))) - (when (zerop arg) - (setq arg 1)) - (compat-call - set-transient-map - (let ((map (make-sparse-keymap))) - (dolist (key '(?= ?- ?0)) - (let ((a (pcase key - (?0 0) - (?- (- (abs arg))) - (_ (abs arg))))) - (define-key map (vector (list key)) - (lambda () - (interactive) - (cl-incf total (erc-fill--wrap-nudge a)) - (recenter line))))) - (dolist (key '(?\) ?_ ?+)) - (let ((a (pcase key - (?\) 0) - (?_ (if leftp (abs arg) (- (abs arg)))) - (?+ (if leftp (- (abs arg)) (abs arg)))))) - (define-key map (vector (list key)) - (lambda () - (interactive) - (erc-stamp--adjust-margin (- a) (zerop a)) - (when leftp (erc-stamp--refresh-left-margin-prompt)) - (recenter line))))) - map) - t - (lambda () - (message "Fill prefix: %d (%+d col%s); Margin: %d" - erc-fill--wrap-value total (if (> (abs total) 1) "s" "") - (if leftp left-margin-width right-margin-width))) - "Use %k for further adjustment" - 1) - (recenter line))) - -(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 - ;; FIXME use a more robust test than symbol equivalence. - (eq erc-insert-timestamp-function 'erc-insert-timestamp-left) - (not erc-hide-timestamps)) - (length (format-time-string erc-timestamp-format)) - 0)) - -(cl-defmethod erc--determine-fill-column-function - (&context (erc-fill-mode (eql t))) - (if erc-fill-wrap-mode - (- (window-width) erc-fill--wrap-value 1) - erc-fill-column)) - -(provide 'erc-fill) - -;;; erc-fill.el ends here -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el deleted file mode 100644 index 1cf1d196786..00000000000 --- a/lisp/erc/erc-goodies.el +++ /dev/null @@ -1,1161 +0,0 @@ -;;; erc-goodies.el --- Collection of ERC modules -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2025 Free Software Foundation, Inc. - -;; Author: Jorgen Schaefer -;; Maintainer: Amin Bandali , F. Jason Park - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This provides some small but still useful modes for ERC. - -;;; Code: - -(eval-when-compile (require 'cl-lib)) -(require 'erc) - -(declare-function fringe-columns "fringe" (side &optional real)) -(declare-function pulse-available-p "pulse" nil) -(declare-function pulse-momentary-highlight-overlay "pulse" (o &optional face)) - - -;;; 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', unless `erc-scrolltobottom-all' is -`relaxed', in which case, ERC interprets it as additional lines -to scroll down by per message insertion (minus one for the -prompt)." - :group 'erc-display - :type '(choice integer (const nil))) - -(defcustom erc-scrolltobottom-all nil - "Whether to scroll all windows or just the selected one. -ERC expects this option to be configured before module -initialization. A value of nil preserves pre-5.6 behavior, in -which scrolling only affects the selected window. A value of t -means ERC attempts to recenter all visible windows whose point -resides in the input area. - -A value of `relaxed' tells ERC to forgo forcing prompt to the -bottom of the window. When point is at the prompt, ERC scrolls -the window up when inserting messages, making the prompt appear -stationary. Users who find this effect too \"stagnant\" can -adjust the option `erc-input-line-position', borrowed here to -express a scroll step offset. Setting that value to zero lets -the prompt drift toward the bottom by one line per message, which -is generally slow enough not to distract while composing input. -Of course, this doesn't apply when receiving a large influx of -messages, such as after typing \"/msg NickServ help\". - -Note that users should consider this option's non-nil behavior to -be experimental. It currently only works with Emacs 28+." - :group 'erc-display - :package-version '(ERC . "5.6") - :type '(choice boolean (const relaxed))) - -;;;###autoload(autoload 'erc-scrolltobottom-mode "erc-goodies" nil t) -(define-erc-module scrolltobottom nil - "This mode causes the prompt to stay at the end of the window." - ((add-hook 'erc-mode-hook #'erc--scrolltobottom-setup) - (when (and erc-scrolltobottom-all (< emacs-major-version 28)) - (erc-button--display-error-notice-with-keys - "Option `erc-scrolltobottom-all' requires Emacs 28+. Disabling.") - (setq erc-scrolltobottom-all nil)) - (unless erc--updating-modules-p (erc-buffer-do #'erc--scrolltobottom-setup)) - (if erc-scrolltobottom-all - (progn - (add-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert 25) - (add-hook 'erc-pre-send-functions #'erc--scrolltobottom-on-pre-insert) - (add-hook 'erc-insert-done-hook #'erc--scrolltobottom-all) - (add-hook 'erc-send-completed-hook #'erc--scrolltobottom-all)) - (add-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom))) - ((remove-hook 'erc-mode-hook #'erc--scrolltobottom-setup) - (erc-buffer-do #'erc--scrolltobottom-setup) - (remove-hook 'erc-insert-pre-hook #'erc--scrolltobottom-on-pre-insert) - (remove-hook 'erc-send-completed-hook #'erc--scrolltobottom-all) - (remove-hook 'erc-insert-done-hook #'erc--scrolltobottom-all) - (remove-hook 'erc-pre-send-functions #'erc--scrolltobottom-on-pre-insert) - (remove-hook 'erc-insert-done-hook #'erc-possibly-scroll-to-bottom))) - -(defun erc-possibly-scroll-to-bottom () - "Like `erc-add-scroll-to-bottom', but only if window is selected." - (when (eq (selected-window) (get-buffer-window)) - (erc-scroll-to-bottom))) - -(defvar-local erc--scrolltobottom-window-info nil - "Alist with windows as keys and lists of window-related info as values. -Values are lists containing the last window start position and -the last \"window line\" of point. The \"window line\", which -may be nil, is the number of lines between `window-start' and -`window-point', inclusive.") - -;; FIXME treat `end-of-buffer' specially and always recenter -1. -;; FIXME make this work when `erc-scrolltobottom-all' is set to -;; `relaxed'. -(defvar erc--scrolltobottom-post-ignore-commands '(text-scale-adjust) - "Commands to skip instead of force-scroll on `post-command-hook'.") - -(defun erc--scrolltobottom-on-post-command () - "Scroll selected window unless `this-command' is exempted." - (when (eq (selected-window) (get-buffer-window)) - (unless (memq this-command erc--scrolltobottom-post-ignore-commands) - (setq erc--scrolltobottom-window-info nil) - (erc--scrolltobottom-confirm)))) - -;; It may be desirable to also restore the relative line position of -;; window point after changing dimensions. Perhaps stashing the -;; previous ratio of window line to body height and later recentering -;; proportionally would achieve this. -(defun erc--scrolltobottom-on-win-conf-change () - "Scroll window to bottom when at prompt and using the minibuffer." - (setq erc--scrolltobottom-window-info nil) - (erc--scrolltobottom-confirm)) - -(defun erc--scrolltobottom-all (&rest _) - "Maybe put prompt on last line in all windows displaying current buffer. -Expect to run when narrowing is in effect, such as on insertion -or send-related hooks. When recentering has not been performed, -attempt to restore last `window-start', if known." - (dolist (window (get-buffer-window-list nil nil 'visible)) - (with-selected-window window - (when-let - ((erc--scrolltobottom-window-info) - (found (assq window erc--scrolltobottom-window-info)) - ((not (erc--scrolltobottom-confirm (nth 2 found))))) - (set-window-start window (cadr found) 'no-force)))) - ;; Necessary unless we're sure `erc--scrolltobottom-on-pre-insert' - ;; always runs between calls to this function. - (setq erc--scrolltobottom-window-info nil)) - -(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'. - -Note that the prior suggestion comes from a time when this -function used `window-scroll-functions', which was replaced by -`post-command-hook' in ERC 5.3." - (declare (obsolete erc--scrolltobottom-setup "30.1")) - (add-hook 'post-command-hook #'erc-scroll-to-bottom nil t)) - -(defun erc--scrolltobottom-setup () - "Perform buffer-local setup for module `scrolltobottom'." - (if erc-scrolltobottom-mode - (if erc-scrolltobottom-all - (progn - (when (zerop scroll-conservatively) - (setq-local scroll-step 1)) - (unless (eq erc-scrolltobottom-all 'relaxed) - (add-hook 'window-configuration-change-hook - #'erc--scrolltobottom-on-win-conf-change 50 t) - (add-hook 'post-command-hook - #'erc--scrolltobottom-on-post-command 50 t))) - (add-hook 'post-command-hook #'erc-scroll-to-bottom nil t)) - (remove-hook 'post-command-hook #'erc-scroll-to-bottom t) - (remove-hook 'post-command-hook #'erc--scrolltobottom-on-post-command t) - (remove-hook 'window-configuration-change-hook - #'erc--scrolltobottom-on-win-conf-change t) - (kill-local-variable 'scroll-step) - (kill-local-variable 'erc--scrolltobottom-window-info))) - -(defun erc--scrolltobottom-on-pre-insert (_) - "Remember `window-start' before inserting a message." - (setq erc--scrolltobottom-window-info - (mapcar (lambda (w) - (list w - (window-start w) - (and-let* - (((eq erc-scrolltobottom-all 'relaxed)) - (c (count-screen-lines (window-start w) - (point-max) nil w))) - (if (= ?\n (char-before (point-max))) (1+ c) c)))) - (get-buffer-window-list nil nil 'visible)))) - -(defun erc--scrolltobottom-confirm (&optional scroll-to) - "Like `erc-scroll-to-bottom', but use `window-point'. -Position current line (with `recenter') SCROLL-TO lines below -window's top. Return nil if point is not in prompt area or if -prompt isn't ready." - (when erc-insert-marker - (let ((resize-mini-windows nil)) - (save-restriction - (widen) - (when (>= (window-point) erc-input-marker) - (save-excursion - (goto-char (point-max)) - (recenter (+ (or scroll-to 0) (or erc-input-line-position -1))) - t)))))) - -(defun erc-scroll-to-bottom () - "Recenter WINDOW so that `point' is on the last line. - -You can control which line is recentered to by customizing the -variable `erc-input-line-position'." - ;; 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-restriction - (widen) - (when (and erc-insert-marker - (eq (current-buffer) (window-buffer)) - ;; we're editing a line. Scroll. - (> (point) erc-insert-marker)) - (save-excursion - (goto-char (point-max)) - (recenter (or erc-input-line-position -1))))))) - -;;; Make read only -;;;###autoload(autoload 'erc-readonly-mode "erc-goodies" nil t) -(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 70) - (add-hook 'erc-send-post-hook #'erc-make-read-only 70)) - ((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)) - -;;; Move to prompt when typing text -;;;###autoload(autoload 'erc-move-to-prompt-mode "erc-goodies" nil t) -(define-erc-module move-to-prompt nil - "This mode causes the point to be moved to the prompt when typing text." - ((add-hook 'erc-mode-hook #'erc-move-to-prompt-setup) - (unless erc--updating-modules-p (erc-buffer-do #'erc-move-to-prompt-setup))) - ((remove-hook 'erc-mode-hook #'erc-move-to-prompt-setup) - (dolist (buffer (erc-buffer-list)) - (with-current-buffer buffer - (remove-hook 'pre-command-hook #'erc-move-to-prompt t))))) - -(defun erc-move-to-prompt () - "Move the point to the ERC prompt if this is a self-inserting command." - (when (and erc-input-marker (< (point) erc-input-marker) - (eq 'self-insert-command this-command)) - (deactivate-mark) - (push-mark) - (goto-char (point-max)))) - -(defun erc-move-to-prompt-setup () - "Initialize the move-to-prompt module." - (add-hook 'pre-command-hook #'erc-move-to-prompt 70 t)) - -;;; Keep place in unvisited channels -;;;###autoload(autoload 'erc-keep-place-mode "erc-goodies" nil t) -(define-erc-module keep-place nil - "Leave point above un-viewed text in other channels." - ((add-hook 'erc-insert-pre-hook #'erc-keep-place 65)) - ((remove-hook 'erc-insert-pre-hook #'erc-keep-place))) - -(defcustom erc-keep-place-indicator-style t - "Flavor of visual indicator applied to kept place. -For use with the `keep-place-indicator' module. A value of `arrow' -displays an arrow in the left fringe or margin. When it's -`face', ERC adds the face `erc-keep-place-indicator-line' to the -appropriate line. A value of t does both." - :group 'erc - :package-version '(ERC . "5.6") - :type '(choice (const :tag "Use arrow" arrow) - (const :tag "Use face" face) - (const :tag "Use both arrow and face" t))) - -(defcustom erc-keep-place-indicator-buffer-type t - "ERC buffer type in which to display `keep-place-indicator'. -A value of t means \"all\" ERC buffers." - :group 'erc - :package-version '(ERC . "5.6") - :type '(choice (const t) (const server) (const target))) - -(defcustom erc-keep-place-indicator-follow nil - "Whether to sync visual kept place to window's top when reading. -For use with `erc-keep-place-indicator-mode'. When enabled, the -indicator updates when the last window displaying the same buffer -switches away, but only if the indicator resides earlier in the -buffer than the window's start." - :group 'erc - :package-version '(ERC . "5.6") - :type 'boolean) - -(defcustom erc-keep-place-indicator-truncation nil - "What to do when truncation occurs and the buffer is trimmed. -If nil, a truncation event moves the indicator, effectively resetting it -to `point-min'. If this option's value is t, the indicator stays put -and limits the operation, but only when it resides on an actual message. -That is, if it remains at its initial position at or near `point-min', -truncation will still occur. As of ERC 5.6.1, this option only -influences the behavior of the `truncate' module, rather than truncation -resulting from a /CLEAR." - :group 'erc - :package-version '(ERC . "5.6.1") - :type 'boolean) - -(defface erc-keep-place-indicator-line - '((((class color) (min-colors 88) (background light) - (supports :underline (:style wave))) - (:underline (:color "PaleGreen3" :style wave))) - (((class color) (min-colors 88) (background dark) - (supports :underline (:style wave))) - (:underline (:color "PaleGreen1" :style wave))) - (t :underline t)) - "Face for option `erc-keep-place-indicator-style'." - :group 'erc-faces) - -(defface erc-keep-place-indicator-arrow - '((((class color) (min-colors 88) (background light)) - (:foreground "PaleGreen3")) - (((class color) (min-colors 88) (background dark)) - (:foreground "PaleGreen1")) - (t :inherit fringe)) - "Face for arrow value of option `erc-keep-place-indicator-style'." - :group 'erc-faces) - -(defvar-local erc--keep-place-indicator-overlay nil - "Overlay for `erc-keep-place-indicator-mode'.") - -(defun erc--keep-place-indicator-on-window-buffer-change (_) - "Maybe sync `erc--keep-place-indicator-overlay'. -Do so only when switching to a new buffer in the same window if -the replaced buffer is no longer visible in another window and -its `window-start' at the time of switching is strictly greater -than the indicator's position." - (when-let ((erc-keep-place-indicator-follow) - (window (selected-window)) - ((not (eq window (active-minibuffer-window)))) - (old-buffer (window-old-buffer window)) - ((buffer-live-p old-buffer)) - ((not (eq old-buffer (current-buffer)))) - (ov (buffer-local-value 'erc--keep-place-indicator-overlay - old-buffer)) - ((not (get-buffer-window old-buffer 'visible))) - (prev (assq old-buffer (window-prev-buffers window))) - (old-start (nth 1 prev)) - (old-inmkr (buffer-local-value 'erc-insert-marker old-buffer)) - ((< (overlay-end ov) old-start old-inmkr))) - (with-current-buffer old-buffer - (erc-keep-place-move old-start)))) - -;;;###autoload(put 'keep-place-indicator 'erc--feature 'erc-goodies) -;;;###autoload(autoload 'erc-keep-place-indicator-mode "erc-goodies" nil t) -(define-erc-module keep-place-indicator nil - "Buffer-local `keep-place' with fringe arrow and/or highlighted face. -Play nice with global module `keep-place' but don't depend on it. -Expect that users may want different combinations of `keep-place' -and `keep-place-indicator' in different buffers. - -This module is local to individual buffers." - ((cond (erc-keep-place-mode) - ((memq 'keep-place erc-modules) - (erc-keep-place-mode +1)) - ;; Enable a local version of `keep-place-mode'. - (t (add-hook 'erc-insert-pre-hook #'erc-keep-place 65 t))) - (require 'fringe) - (add-hook 'window-buffer-change-functions - #'erc--keep-place-indicator-on-window-buffer-change 40) - (add-hook 'erc-keep-place-mode-hook - #'erc--keep-place-indicator-on-global-module 40) - (add-function :before (local 'erc--clear-function) - #'erc--keep-place-indicator-adjust-on-clear '((depth . 40))) - (if (pcase erc-keep-place-indicator-buffer-type - ('target erc--target) - ('server (not erc--target)) - ('t t)) - (progn - (erc--restore-initialize-priors erc-keep-place-indicator-mode - erc--keep-place-indicator-overlay (make-overlay 0 0)) - (when-let (((memq erc-keep-place-indicator-style '(t arrow))) - (ov-property (if (zerop (fringe-columns 'left)) - 'after-string - 'before-string)) - (display (if (zerop (fringe-columns 'left)) - `((margin left-margin) ,overlay-arrow-string) - '(left-fringe right-triangle - erc-keep-place-indicator-arrow))) - (bef (propertize " " 'display display))) - (overlay-put erc--keep-place-indicator-overlay ov-property bef)) - (when (memq erc-keep-place-indicator-style '(t face)) - (overlay-put erc--keep-place-indicator-overlay 'face - 'erc-keep-place-indicator-line))) - (erc-keep-place-indicator-mode -1))) - ((when erc--keep-place-indicator-overlay - (delete-overlay erc--keep-place-indicator-overlay)) - (let ((buffer (current-buffer))) - ;; Remove global hooks unless others exist with mode enabled. - (unless (erc-buffer-filter (lambda () - (and (not (eq buffer (current-buffer))) - erc-keep-place-indicator-mode))) - (remove-hook 'erc-keep-place-mode-hook - #'erc--keep-place-indicator-on-global-module) - (remove-hook 'window-buffer-change-functions - #'erc--keep-place-indicator-on-window-buffer-change) - (remove-function (local 'erc--clear-function) - #'erc--keep-place-indicator-adjust-on-clear))) - (when (local-variable-p 'erc-insert-pre-hook) - (remove-hook 'erc-insert-pre-hook #'erc-keep-place t)) - (remove-hook 'erc-keep-place-mode-hook - #'erc--keep-place-indicator-on-global-module t) - (kill-local-variable 'erc--keep-place-indicator-overlay)) - localp) - -(defun erc--keep-place-indicator-on-global-module () - "Ensure `keep-place-indicator' survives toggling `erc-keep-place-mode'. -Do this by simulating `keep-place' in all buffers where -`keep-place-indicator' is enabled." - (erc-with-all-buffers-of-server nil (lambda () erc-keep-place-indicator-mode) - (if erc-keep-place-mode - (remove-hook 'erc-insert-pre-hook #'erc-keep-place t) - (add-hook 'erc-insert-pre-hook #'erc-keep-place 65 t)))) - -(defvar erc--keep-place-move-hook nil - "Hook run when `erc-keep-place-move' moves the indicator.") - -(defun erc--keep-place-indicator-adjust-on-clear (beg end) - "Either shrink region bounded by BEG to END to preserve overlay, or reset." - (when-let ((pos (overlay-start erc--keep-place-indicator-overlay)) - ((<= beg pos end))) - (if (and erc-keep-place-indicator-truncation - (not erc--called-as-input-p)) - (when-let ((pos (erc--get-inserted-msg-beg pos))) - (set-marker end pos)) - (let (erc--keep-place-move-hook) - ;; Move earlier than `beg', which may delimit date stamps, etc. - (erc-keep-place-move (point-min)))))) - -(defun erc-keep-place-move (pos) - "Move keep-place indicator to current line or POS. -For use with `keep-place-indicator' module. When called -interactively, interpret POS as an offset. Specifically, when -POS is a raw prefix arg, like (4), move the indicator to the -window's last line. When it's the minus sign, put it on the -window's first line. Interpret an integer as an offset in lines." - (interactive - (progn - (unless erc-keep-place-indicator-mode - (user-error "`erc-keep-place-indicator-mode' not enabled")) - (list (pcase current-prefix-arg - ((and (pred integerp) v) - (save-excursion - (let ((inhibit-field-text-motion t)) - (forward-line v) - (point)))) - (`(,_) (1- (min erc-insert-marker (window-end)))) - ('- (min (1- erc-insert-marker) (window-start))))))) - (save-excursion - (let ((inhibit-field-text-motion t)) - (when pos - (goto-char pos)) - (when-let ((pos (erc--get-inserted-msg-beg))) - (goto-char pos)) - (run-hooks 'erc--keep-place-move-hook) - (move-overlay erc--keep-place-indicator-overlay - (line-beginning-position) - (line-end-position))))) - -(defun erc-keep-place-goto () - "Jump to keep-place indicator. -For use with `keep-place-indicator' module." - (interactive - (prog1 nil - (unless erc-keep-place-indicator-mode - (user-error "`erc-keep-place-indicator-mode' not enabled")) - (deactivate-mark) - (push-mark))) - (goto-char (overlay-start erc--keep-place-indicator-overlay)) - (recenter (truncate (* (window-height) 0.25)) t) - (require 'pulse) - (when (pulse-available-p) - (pulse-momentary-highlight-overlay erc--keep-place-indicator-overlay))) - -(defun erc-keep-place (_ignored) - "Move point away from the last line in a non-selected ERC buffer." - (when (and (not (eq (window-buffer (selected-window)) - (current-buffer))) - (>= (point) erc-insert-marker)) - (deactivate-mark) - (goto-char (erc-beg-of-input-line)) - (forward-line -1) - (when erc-keep-place-indicator-mode - (unless (or (minibuffer-window-active-p (selected-window)) - (get-buffer-window nil 'visible)) - (erc-keep-place-move nil))) - ;; if `switch-to-buffer-preserve-window-point' is set, - ;; we cannot rely on point being saved, and must commit - ;; it to window-prev-buffers. - (when switch-to-buffer-preserve-window-point - (dolist (frame (frame-list)) - (walk-window-tree - (lambda (window) - (let ((prev (assq (current-buffer) - (window-prev-buffers window)))) - (when prev - (setf (nth 2 prev) (point-marker))))) - frame nil 'nominibuf))))) - -;;; Distinguish non-commands -(defvar erc-noncommands-list '(erc-cmd-ME - erc-cmd-COUNTRY - erc-cmd-SV - erc-cmd-SM - erc-cmd-SAY - erc-cmd-LASTLOG) - "List of client \"slash commands\" that perform their own buffer I/O. -The `command-indicator' module forgoes echoing these commands, -most of which aren't actual interactive lisp commands.") - -;;;###autoload(autoload 'erc-noncommands-mode "erc-goodies" nil t) -(define-erc-module noncommands nil - "Treat commands that display themselves specially. -This module has been a no-op since ERC 5.3 and has likely only -ever made sense in the context of `erc-command-indicator'. It -was deprecated in ERC 5.6." - ((add-hook 'erc--input-review-functions #'erc-send-distinguish-noncommands)) - ((remove-hook 'erc--input-review-functions - #'erc-send-distinguish-noncommands))) -(make-obsolete-variable 'erc-noncommand-mode - 'erc-command-indicator-mode "30.1") -(make-obsolete 'erc-noncommand-mode 'erc-command-indicator-mode "30.1") -(make-obsolete 'erc-noncommand-enable 'erc-command-indicator-enable "30.1") -(make-obsolete 'erc-noncommand-disable 'erc-command-indicator-disable "30.1") - -(defun erc-send-distinguish-noncommands (state) - "If STR is an ERC non-command, set `insertp' in STATE to nil." - (let* ((string (erc-input-string state)) - (command (erc-extract-command-from-line string)) - (cmd-fun (and command - (car command)))) - (when (and cmd-fun - (not (string-match "\n.+$" string)) - (memq cmd-fun erc-noncommands-list)) - ;; Inhibit sending this string. - (setf (erc-input-insertp state) nil)))) - - -;;; Command-indicator - -(defface erc-command-indicator-face - '((t :inherit (erc-input-face fixed-pitch-serif))) - "Face for echoed command lines, including the prompt. -See option `erc-command-indicator'." - :package-version '(ERC . "5.6") ; standard value, from bold - :group 'erc-faces) - -(defcustom erc-command-indicator 'erc-prompt - "Pseudo prompt for echoed command lines. -An analog of the option `erc-prompt' that replaces the \"speaker -label\" for echoed \"slash\" commands submitted at the prompt. A -value of nil means ERC only inserts the command-line portion -alone, without the prompt, which may trick certain modules, like -`fill', into treating the leading slash command itself as the -message's speaker." - :package-version '(ERC . "5.6") - :group 'erc-display - :type '(choice (const :tag "Defer to `erc-prompt'" erc-prompt) - (const :tag "Print command lines without a prompt" nil) - (string :tag "User-provided string") - (function :tag "User-provided function"))) - -;;;###autoload(autoload 'erc-command-indicator-mode "erc-goodies" nil t) -(define-erc-module command-indicator nil - "Echo command lines for \"slash commands,\" like /JOIN, /HELP, etc. -Skip those appearing in `erc-noncommands-list'. - -Users can run \\[erc-command-indicator-toggle-hidden] to hide and -reveal echoed command lines after they've been inserted. - -This module is local to individual buffers." - ((add-hook 'erc--input-review-functions - #'erc--command-indicator-permit-insertion 80 t) - (erc-command-indicator-toggle-hidden -1)) - ((remove-hook 'erc--input-review-functions - #'erc--command-indicator-permit-insertion t) - (erc-command-indicator-toggle-hidden +1)) - localp) - -(defun erc-command-indicator () - "Return the command-indicator prompt as a string. -Do nothing if the variable `erc-command-indicator' is nil." - (and erc-command-indicator - (let ((prompt (if (functionp erc-command-indicator) - (funcall erc-command-indicator) - erc-command-indicator))) - (concat prompt (and (not (string-empty-p prompt)) - (not (string-suffix-p " " prompt)) - " "))))) - -(defun erc-command-indicator-toggle-hidden (arg) - "Toggle whether echoed \"slash commands\" are visible." - (interactive "P") - (erc--toggle-hidden 'command-indicator arg)) - -(defun erc--command-indicator-permit-insertion (state) - "Insert `erc-input' STATE's message if it's an echoed command." - (cl-assert erc-command-indicator-mode) - (when (erc--input-split-cmdp state) - (setf (erc--input-split-insertp state) t - (erc--input-split-substxt state) #'erc--command-indicator-display) - (erc-send-distinguish-noncommands state))) - -;; This function used to be called `erc-display-command'. It was -;; neutered in ERC 5.3.x (Emacs 24.5), commented out in 5.4, removed -;; in 5.5, and restored in 5.6. -(defun erc--command-indicator-display (line &rest rest) - "Insert command LINE as echoed input resembling that of REPLs and shells." - (when erc-insert-this - (when rest - (setq line (string-join (cons line rest) "\n"))) - (save-excursion - (erc--assert-input-bounds) - (let ((insert-position (marker-position (goto-char erc-insert-marker))) - (erc--msg-props (or erc--msg-props - (let ((ovs erc--msg-prop-overrides)) - (map-into `((erc--msg . slash-cmd) - ,@(reverse ovs)) - 'hash-table))))) - (when-let ((string (erc-command-indicator)) - (erc-input-marker (copy-marker erc-input-marker))) - (erc-display-prompt nil nil string 'erc-command-indicator-face) - (remove-text-properties insert-position (point) - '(field nil erc-prompt nil)) - (set-marker erc-input-marker nil)) - (let ((beg (point))) - (insert line) - (erc-put-text-property beg (point) - 'font-lock-face 'erc-command-indicator-face) - (insert "\n")) - (save-restriction - (narrow-to-region insert-position (point)) - (run-hooks 'erc-send-modify-hook) - (run-hooks 'erc-send-post-hook) - (cl-assert (> (- (point-max) (point-min)) 1)) - (erc--hide-message 'command-indicator) - (add-text-properties (point-min) (1+ (point-min)) - (erc--order-text-properties-from-hash - erc--msg-props)))) - (erc--refresh-prompt)))) - -;;;###autoload -(defun erc-load-irc-script-lines (lines &optional force noexpand) - "Process a list of LINES as prompt input submissions. -If optional NOEXPAND is non-nil, do not expand script-specific -substitution sequences via `erc-process-script-line' and instead -process LINES as literal prompt input. With FORCE, bypass flood -protection." - ;; The various erc-cmd-CMDs were designed to return non-nil when - ;; their command line should be echoed. But at some point, these - ;; handlers began displaying their own output, which naturally - ;; appeared *above* the echoed command. This tries to intercept - ;; these insertions, deferring them until the command has returned - ;; and its command line has been printed. - (cl-assert (eq 'erc-mode major-mode)) - (let ((args (and erc-script-args - (if (string-match "^ " erc-script-args) - (substring erc-script-args 1) - erc-script-args)))) - (with-silent-modifications - (dolist (line lines) - (erc-log (concat "erc-load-script: CMD: " line)) - (unless (string-match (rx bot (* (syntax whitespace)) eot) line) - (unless noexpand - (setq line (erc-process-script-line line args))) - (let ((erc--current-line-input-split (erc--make-input-split line)) - calls insertp) - (add-function :around (local 'erc--send-message-nested-function) - (lambda (&rest args) (push args calls)) - '((name . erc-script-lines-fn) (depth . -80))) - (add-function :around (local 'erc--send-action-function) - (lambda (&rest args) (push args calls)) - '((name . erc-script-lines-fn) (depth . -80))) - (setq insertp - (unwind-protect (erc-process-input-line line force) - (remove-function (local 'erc--send-action-function) - 'erc-script-lines-fn) - (remove-function (local 'erc--send-message-nested-function) - 'erc-script-lines-fn))) - (when (and insertp erc-script-echo) - (erc--command-indicator-display line) - (dolist (call calls) - (apply (car call) (cdr call)))))))))) - -;;; 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 colors 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'." - :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." - :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." - :type 'boolean) - -(defface erc-bold-face '((t :weight bold)) - "ERC bold face." - :group 'erc-faces) - -(defface erc-italic-face '((t :slant italic)) - "ERC italic face." - :group 'erc-faces) - -(defface erc-inverse-face - '((t :inverse-video t)) - "ERC inverse face." - :group 'erc-faces) - -(defface erc-spoiler-face '((t :inherit default)) - "ERC spoiler face." - :group 'erc-faces) - -(defface erc-underline-face '((t :underline t)) - "ERC underline face." - :group 'erc-faces) - -;; FIXME rename these to something like `erc-control-color-N-fg', -;; and deprecate the old names via `define-obsolete-face-alias'. -(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) - -;; https://lists.gnu.org/archive/html/emacs-erc/2021-07/msg00005.html -(defvar erc--controls-additional-colors - ["#470000" "#472100" "#474700" "#324700" "#004700" "#00472c" - "#004747" "#002747" "#000047" "#2e0047" "#470047" "#47002a" - "#740000" "#743a00" "#747400" "#517400" "#007400" "#007449" - "#007474" "#004074" "#000074" "#4b0074" "#740074" "#740045" - "#b50000" "#b56300" "#b5b500" "#7db500" "#00b500" "#00b571" - "#00b5b5" "#0063b5" "#0000b5" "#7500b5" "#b500b5" "#b5006b" - "#ff0000" "#ff8c00" "#ffff00" "#b2ff00" "#00ff00" "#00ffa0" - "#00ffff" "#008cff" "#0000ff" "#a500ff" "#ff00ff" "#ff0098" - "#ff5959" "#ffb459" "#ffff71" "#cfff60" "#6fff6f" "#65ffc9" - "#6dffff" "#59b4ff" "#5959ff" "#c459ff" "#ff66ff" "#ff59bc" - "#ff9c9c" "#ffd39c" "#ffff9c" "#e2ff9c" "#9cff9c" "#9cffdb" - "#9cffff" "#9cd3ff" "#9c9cff" "#dc9cff" "#ff9cff" "#ff94d3" - "#000000" "#131313" "#282828" "#363636" "#4d4d4d" "#656565" - "#818181" "#9f9f9f" "#bcbcbc" "#e2e2e2" "#ffffff"]) - -(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)) - (prog1 'default - (erc-error "erc-get-bg-color-face: n is NaN: %S" n)) - (when (> n 99) - (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)))) - ((< 15 n 99) - (list :background (aref erc--controls-additional-colors (- n 16)))) - (t (erc-log (format " Wrong color: %s" n)) nil)))) - -(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)) - (prog1 'default - (erc-error "erc-get-fg-color-face: n is NaN: %S" n)) - (when (> n 99) - (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)))) - ((< 15 n 99) - (list :foreground (aref erc--controls-additional-colors (- n 16)))) - (t (erc-log (format " Wrong color: %s" n)) nil)))) - -;;;###autoload(autoload 'erc-irccontrols-mode "erc-goodies" nil t) -(define-erc-module irccontrols nil - "This mode enables the interpretation of IRC control chars." - ((add-hook 'erc-insert-modify-hook #'erc-controls-highlight -50) - (add-hook 'erc-send-modify-hook #'erc-controls-highlight) - (erc--modify-local-map t "C-c C-c" #'erc-toggle-interpret-controls)) - ((remove-hook 'erc-insert-modify-hook #'erc-controls-highlight) - (remove-hook 'erc-send-modify-hook #'erc-controls-highlight) - (erc--modify-local-map nil "C-c C-c" #'erc-toggle-interpret-controls))) - -;; These patterns were moved here to circumvent compiler warnings but -;; otherwise translated verbatim from their original string-literal -;; definitions (minus a small bug fix to satisfy newly added tests). -(defvar erc-controls-remove-regexp - (rx (or ?\C-b ?\C-\] ?\C-_ ?\C-v ?\C-g ?\C-o - (: ?\C-c (? (any "0-9")) (? (any "0-9")) - (? (group ?, (any "0-9") (? (any "0-9"))))))) - "Regular expression matching control characters to remove.") - -;; Before the change to `rx', group 3 used to be a sibling of group 2. -;; This was assumed to be a bug. A few minor simplifications were -;; also performed. If incorrect, please admonish. -(defvar erc-controls-highlight-regexp - (rx (group (or ?\C-b ?\C-\] ?\C-v ?\C-_ ?\C-g ?\C-o - (: ?\C-c (? (group (** 1 2 (any "0-9"))) - (? (group ?, (group (** 1 2 (any "0-9"))))))))) - (group (* (not (any ?\C-b ?\C-c ?\C-g ?\n ?\C-o ?\C-v ?\C-\] ?\C-_))))) - "Regular expression matching control chars to 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) - (italicp 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 (replace-match "" nil nil s 1)) - (cond ((and erc-interpret-mirc-color (or fg-color bg-color)) - (setq fg fg-color) - (when bg-color (setq bg bg-color))) - ((string= control "\C-b") - (setq boldp (not boldp))) - ((string= control "\C-]") - (setq italicp (not italicp))) - ((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 - italicp nil - inversep nil - underlinep nil - fg nil - bg nil)) - (t nil)) - (erc-controls-propertize - start end boldp italicp inversep underlinep fg bg s))) - s)) - (t s))))) - -;;;###autoload -(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))) - -(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) - (italicp 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) - (when bg-color (setq bg bg-color))) - ((string= control "\C-b") - (setq boldp (not boldp))) - ((string= control "\C-]") - (setq italicp (not italicp))) - ((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 - italicp nil - inversep nil - underlinep nil - fg nil - bg nil)) - (t nil)) - (erc-controls-propertize start end - boldp italicp inversep underlinep fg bg))))) - (t nil))) - -(defun erc-controls-propertize (from to boldp italicp 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." - (when (and fg bg (equal fg bg) (not (equal fg "99"))) - (add-text-properties from to '( mouse-face erc-spoiler-face - cursor-face erc-spoiler-face) - str) - (erc--reserve-important-text-props from to - '( mouse-face erc-spoiler-face - cursor-face erc-spoiler-face) - str)) - (when fg (setq fg (erc-get-fg-color-face fg))) - (when bg (setq bg (erc-get-bg-color-face bg))) - (font-lock-prepend-text-property - from - to - 'font-lock-face - (append (if boldp - '(erc-bold-face) - nil) - (if italicp - '(erc-italic-face) - nil) - (if inversep - '(erc-inverse-face) - nil) - (if underlinep - '(erc-underline-face) - nil) - (if fg - (list fg) - nil) - (if bg - (list 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 -;;;###autoload(autoload 'erc-smiley-mode "erc-goodies" nil t) -(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 -;;;###autoload(autoload 'erc-unmorse-mode "erc-goodies" nil t) -(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) - (save-restriction - (narrow-to-region (match-beginning 0) (match-end 0)) - ;; Turn " / " into " " - (goto-char (point-min)) - (while (re-search-forward " / " nil t) - (replace-match " ")) - ;; Turn "/ " into "/" - (goto-char (point-min)) - (while (re-search-forward "/ " nil t) - (replace-match "/")) - ;; Unmorse region - (unmorse-region (point-min) (point-max))))) - -;;; 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))) - (multi-occur (erc-buffer-list nil proc) string)) - - -(provide 'erc-goodies) - -;;; erc-goodies.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-ibuffer.el b/lisp/erc/erc-ibuffer.el deleted file mode 100644 index d90f25d5078..00000000000 --- a/lisp/erc/erc-ibuffer.el +++ /dev/null @@ -1,188 +0,0 @@ -;;; erc-ibuffer.el --- ibuffer integration with ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2002, 2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; 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 - -;; This library does not contain a module, but you can `require' it -;; after loading `erc' to make use of its functionality. - -;;; Code: - -(require 'ibuffer) -(require 'ibuf-ext) -(require 'erc) -(require 'erc-goodies) ; `erc-controls-interpret' - -(defgroup erc-ibuffer nil - "The Ibuffer group for ERC." - :group 'erc) - -(defcustom erc-ibuffer-keyword-char ?k - "Char indicating a channel which had keyword traffic lately (hidden)." - :type 'character) -(defcustom erc-ibuffer-pal-char ?p - "Char indicating a channel which had pal traffic lately (hidden)." - :type 'character) -(defcustom erc-ibuffer-fool-char ?f - "Char indicating a channel which had fool traffic lately (hidden)." - :type 'character) -(defcustom erc-ibuffer-dangerous-host-char ?d - "Char indicating a channel which had dangerous-host traffic lately (hidden)." - :type 'character) - -(define-ibuffer-filter erc-server - "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))))) - -;; Silence the byte-compiler -(defvar erc-modified-channels-alist) - -(define-ibuffer-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 (cdr entry) - (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)) - " ")) - " ")) - -(define-ibuffer-column erc-server-name (:name "Server") - (or - (when (and erc-server-process (processp erc-server-process)) - (let ((buffer (process-buffer erc-server-process))) - (if (buffer-live-p buffer) - (with-current-buffer buffer - (or erc-server-announced-name erc-session-server)) - "(closed)"))) - "")) - -(define-ibuffer-column erc-target (:name "Target") - (if (eq major-mode 'erc-mode) - (cond ((and 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))) - -(define-ibuffer-column erc-topic (:name "Topic") - (if (and (eq major-mode 'erc-mode) - erc-channel-topic) - (erc-controls-interpret erc-channel-topic) - "")) - -(define-ibuffer-column - erc-members (:name "Users") - (if-let ((table (or erc-channel-users erc-server-users)) - ((hash-table-p table)) - (count (hash-table-count table)) - ((> count 0))) - (number-to-string count) - "")) - -(define-ibuffer-column erc-away (:name "A") - (if (and erc-server-process - (processp erc-server-process) - (erc-away-time)) - "A" - " ")) - -(define-ibuffer-column - erc-op (:name "O") - (if (and (eq major-mode 'erc-mode) - (erc-channel-user-op-p (erc-current-nick))) - "@" - " ")) - -(define-ibuffer-column erc-voice (:name "V") - (if (and (eq major-mode 'erc-mode) - (erc-channel-user-voice-p (erc-current-nick))) - "+" - " ")) - -(define-ibuffer-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 (derived-mode-p 'erc-mode)) - (format-mode-line mode-name nil nil (current-buffer)) - ""))) - -(define-ibuffer-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-filter-by-erc-server) -(define-key ibuffer-mode-map (kbd "/ \C-e") 'erc-ibuffer-limit-map) - -(provide 'erc-ibuffer) - -;;; erc-ibuffer.el ends here diff --git a/lisp/erc/erc-identd.el b/lisp/erc/erc-identd.el deleted file mode 100644 index 572ff8f5f48..00000000000 --- a/lisp/erc/erc-identd.el +++ /dev/null @@ -1,119 +0,0 @@ -;;; erc-identd.el --- RFC1413 (identd authentication protocol) server -*- lexical-binding: t; -*- - -;; Copyright (C) 2003, 2006-2025 Free Software Foundation, Inc. - -;; Author: John Wiegley -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This module allows you to run a local identd server on port 8113. -;; You will need to set up DNAT to bind 113->8113, or use a proxy. - -;; To use this module, add identd to `erc-modules' and run -;; `erc-update-modules'. - -;; Here is an example /etc/inetd.conf rule that forwards identd -;; traffic to port 8113. You will need simpleproxy installed for it -;; to work. - -;; 113 stream tcp nowait nobody /usr/sbin/tcpd /usr/bin/simpleproxy simpleproxy -i -R 127.0.0.1:8113 - -;;; Code: - -(require 'erc) - -(defvar erc-identd-process nil) - -(defgroup erc-identd nil - "Run a local identd server." - :group 'erc) - -(defcustom erc-identd-port 8113 - "Port to run the identd server on. -This can be overridden by specifying an argument for -`erc-identd-start'. - -This can be either a string or a number." - :type '(choice (const :tag "None" nil) - (integer :tag "Port number") - (string :tag "Port string"))) - -;;;###autoload(autoload 'erc-identd-mode "erc-identd") -(define-erc-module identd nil - "This mode launches an identd server on port 8113." - ((add-hook 'erc-connect-pre-hook #'erc-identd-quickstart) - (add-hook 'erc-disconnected-hook #'erc-identd-stop)) - ((remove-hook 'erc-connect-pre-hook #'erc-identd-quickstart) - (remove-hook 'erc-disconnected-hook #'erc-identd-stop))) - -(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))) - (stop-process erc-identd-process) - (delete-process proc))))) - -;;;###autoload -(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"))) - (unless port (setq port erc-identd-port)) - (when (stringp port) - (setq port (string-to-number port))) - (when erc-identd-process - (delete-process erc-identd-process)) - (setq erc-identd-process - (make-network-process :name "identd" - :buffer nil - :host 'local :service port - :server t :noquery t :nowait t - :filter #'erc-identd-filter)) - (set-process-query-on-exit-flag erc-identd-process nil)) - -(defun erc-identd-quickstart (&rest _ignored) - "Start the identd server with the default port. -The default port is specified by `erc-identd-port'." - (erc-identd-start)) - -;;;###autoload -(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: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-imenu.el b/lisp/erc/erc-imenu.el deleted file mode 100644 index 2e244fa157e..00000000000 --- a/lisp/erc/erc-imenu.el +++ /dev/null @@ -1,172 +0,0 @@ -;;; erc-imenu.el --- Imenu support for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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: - -;;; 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) - -(defgroup erc-imenu nil - "Imenu integration for ERC." - :group 'erc) - -(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)))) - (inhibit-read-only t)) - (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)) - (while (if (bolp) - (> (forward-line -1) - -1) - (progn (forward-line 0) - 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)) - -(defvar-local erc-imenu--create-index-function nil - "Previous local value of `imenu-create-index-function', if any.") - -;;;###autoload(autoload 'erc-imenu-mode "erc-imenu" nil t) -(define-erc-module imenu nil - "Simple Imenu integration for ERC." - ((add-hook 'erc-mode-hook #'erc-imenu-setup) - (add-hook 'which-function-mode-hook #'erc-imenu--disable-which-func) - (unless erc--updating-modules-p (erc-buffer-do #'erc-imenu-setup))) - ((remove-hook 'erc-mode-hook #'erc-imenu-setup) - (remove-hook 'which-function-mode-hook #'erc-imenu--disable-which-func) - (erc-buffer-do #'erc-imenu-setup))) - -(defun erc-imenu-setup () - "Set up or tear down Imenu integration." - (if erc-imenu-mode - (progn - (when (and (local-variable-p 'imenu-create-index-function) - imenu-create-index-function) - (setq erc-imenu--create-index-function imenu-create-index-function)) - (setq imenu-create-index-function #'erc-create-imenu-index) - (when (boundp 'which-func-mode) - (setq which-func-mode nil))) - (when erc-imenu--create-index-function - (setq imenu-create-index-function erc-imenu--create-index-function)) - (kill-local-variable 'erc-imenu--create-index-function) - (kill-local-variable 'which-func-mode))) - -(defun erc-imenu--disable-which-func () - "Silence `which-function-mode' in ERC buffers." - (defvar which-func-mode) - (erc-with-all-buffers-of-server nil nil - (setq which-func-mode nil))) - -(provide 'erc-imenu) - -;;; erc-imenu.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-join.el b/lisp/erc/erc-join.el deleted file mode 100644 index 5074cba6552..00000000000 --- a/lisp/erc/erc-join.el +++ /dev/null @@ -1,256 +0,0 @@ -;;; erc-join.el --- autojoin channels on connect and reconnects -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Alex Schroeder -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, irc -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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) - -(defgroup erc-autojoin nil - "Enable autojoining." - :group 'erc) - -;;;###autoload(autoload 'erc-autojoin-mode "erc-join" 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-nickserv-identified-hook #'erc-autojoin-after-ident) - (add-hook 'erc-server-JOIN-functions #'erc-autojoin-add) - (add-hook 'erc-server-PART-functions #'erc-autojoin-remove) - (add-hook 'erc-server-405-functions #'erc-join--remove-requested-channel) - (add-hook 'erc-server-471-functions #'erc-join--remove-requested-channel) - (add-hook 'erc-server-473-functions #'erc-join--remove-requested-channel) - (add-hook 'erc-server-474-functions #'erc-join--remove-requested-channel) - (add-hook 'erc-server-475-functions #'erc-join--remove-requested-channel)) - ((remove-hook 'erc-after-connect #'erc-autojoin-channels) - (remove-hook 'erc-nickserv-identified-hook #'erc-autojoin-after-ident) - (remove-hook 'erc-server-JOIN-functions #'erc-autojoin-add) - (remove-hook 'erc-server-PART-functions #'erc-autojoin-remove) - (remove-hook 'erc-server-405-functions #'erc-join--remove-requested-channel) - (remove-hook 'erc-server-471-functions #'erc-join--remove-requested-channel) - (remove-hook 'erc-server-473-functions #'erc-join--remove-requested-channel) - (remove-hook 'erc-server-474-functions #'erc-join--remove-requested-channel) - (remove-hook 'erc-server-475-functions #'erc-join--remove-requested-channel) - (erc-buffer-do (lambda () - (kill-local-variable 'erc-join--requested-channels))))) - -(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. SERVER can also be a symbol, in which case -it's matched against a non-nil `:id' passed to `erc' or `erc-tls' -when connecting or the value of the current `erc-network' instead of -`erc-server-announced-name' or `erc-session-server' (this can be -useful when connecting to an IRC proxy that relays several -networks under the same server). - -Note that for historical reasons, this option is mutated at runtime, -which is regrettable but here to stay. Please double check the value -before saving it to a `custom-file'. - -If the channel(s) require channel keys for joining, the passwords -are found via auth-source. For instance, if you use ~/.authinfo -as your auth-source backend, then put something like the -following in that file: - -machine irc.example.net login \"#fsf\" password sEcReT - -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." - :type '(alist :options (Libera.Chat) - :key-type (choice :tag "Server" - (symbol :tag "Network") - (regexp :tag "Host or domain")) - :value-type (repeat :tag "Channels" (string :tag "Name")))) - -(defcustom erc-autojoin-timing 'connect - "When ERC should attempt to autojoin a channel. -If the value is `connect', autojoin immediately on connecting. -If the value is `ident', autojoin after successful NickServ -identification, or after `erc-autojoin-delay' seconds. -Any other value means the same as `connect'." - :version "24.1" - :type '(choice (const :tag "On Connection" connect) - (const :tag "When Identified" ident))) - -(defcustom erc-autojoin-delay 30 - "Number of seconds to wait before attempting to autojoin channels. -This only takes effect if `erc-autojoin-timing' is `ident'. -If NickServ identification occurs before this delay expires, ERC -autojoins immediately at that time." - :version "24.1" - :type 'integer) - -(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." - :type 'boolean) - -(defvar-local erc--autojoin-timer nil) - -(defun erc-autojoin-channels-delayed (server nick buffer) - "Attempt to autojoin channels. -This is called from a timer set up by `erc-autojoin-channels'." - (if erc--autojoin-timer - (setq erc--autojoin-timer - (cancel-timer erc--autojoin-timer))) - (with-current-buffer buffer - ;; Don't kick of another delayed autojoin or try to wait for - ;; another ident response: - (let ((erc-autojoin-delay -1) - (erc-autojoin-timing 'connect)) - (erc-log "Delayed autojoin started (no ident success detected yet)") - (erc-autojoin-channels server nick)))) - -(defun erc-autojoin-server-match (candidate) - "Match the current network ID or server against CANDIDATE. -CANDIDATE is a key from `erc-autojoin-channels-alist'. Return the -matching entity, either a string or a non-nil symbol (in the case of a -network or a network ID). Return nil on failure." - (if (symbolp candidate) - (eq (or (erc-networks--id-given erc-networks--id) (erc-network)) - candidate) - (when (stringp candidate) - (string-match-p candidate (or erc-server-announced-name - erc-session-server))))) - -(defvar-local erc-join--requested-channels nil - "List of channels for which an outgoing JOIN was sent.") - -;; Assume users will update their `erc-autojoin-channels-alist' when -;; encountering errors, like a 475 ERR_BADCHANNELKEY. -(defun erc-join--remove-requested-channel (_ parsed) - "Remove channel from `erc-join--requested-channels'." - (when-let ((channel (cadr (erc-response.command-args parsed))) - ((member channel erc-join--requested-channels))) - (setq erc-join--requested-channels - (delete channel erc-join--requested-channels))) - nil) - -(cl-defmethod erc--server-determine-join-display-context - (channel alist &context (erc-autojoin-mode (eql t))) - "Add item to `erc-display-context' ALIST if CHANNEL was autojoined." - (when (member channel erc-join--requested-channels) - (setq erc-join--requested-channels - (delete channel erc-join--requested-channels)) - (push (cons 'erc-autojoin-mode channel) alist)) - (cl-call-next-method channel alist)) - -(defun erc-autojoin--join () - ;; This is called in the server buffer - (pcase-dolist (`(,name . ,channels) erc-autojoin-channels-alist) - (when-let ((match (erc-autojoin-server-match name))) - (dolist (chan channels) - (let ((buf (erc-get-buffer chan erc-server-process))) - (unless (and buf (with-current-buffer buf - (erc--current-buffer-joined-p))) - (push chan erc-join--requested-channels) - (erc-server-join-channel nil chan))))))) - -(defun erc-autojoin-after-ident (_network _nick) - "Autojoin channels in `erc-autojoin-channels-alist'. -This function is run from `erc-nickserv-identified-hook'." - (when (eq erc-autojoin-timing 'ident) - (erc-autojoin--join))) - -(defun erc-autojoin-channels (server nick) - "Autojoin channels in `erc-autojoin-channels-alist'." - (if (eq erc-autojoin-timing 'ident) - ;; Prepare the delayed autojoin timer, in case ident doesn't - ;; happen within the allotted time limit: - (when (> erc-autojoin-delay 0) - (setq erc--autojoin-timer - (run-with-timer erc-autojoin-delay nil - #'erc-autojoin-channels-delayed - server nick (current-buffer)))) - ;; `erc-autojoin-timing' is `connect': - (erc-autojoin--join))) - -(defun erc-autojoin-current-server () - "Compute the current server for lookup in `erc-autojoin-channels-alist'. -Respects `erc-autojoin-domain-only'." - (let ((server (or erc-server-announced-name erc-session-server))) - (if (and erc-autojoin-domain-only - (string-match "[^.\n]+\\.\\([^.\n]+\\.[^.\n]+\\)$" server)) - (match-string 1 server) - server))) - -(defun erc-autojoin--mutate (proc parsed remove) - (when-let* ((nick (car (erc-parse-user (erc-response.sender parsed)))) - ((erc-current-nick-p nick)) - (chnl (car (erc-response.command-args parsed))) - (elem (or (and (erc--valid-local-channel-p chnl) - (regexp-quote erc-server-announced-name)) - (erc-networks--id-given erc-networks--id) - (erc-network) - (with-current-buffer (process-buffer proc) - (erc-autojoin-current-server)))) - (test (if (symbolp elem) #'eq #'equal))) - (if remove - (let ((cs (delete chnl (assoc-default elem erc-autojoin-channels-alist - test)))) - (setf (alist-get elem erc-autojoin-channels-alist nil (null cs) test) - cs)) - (cl-pushnew chnl - (alist-get elem erc-autojoin-channels-alist nil nil test) - :test #'equal)))) - -(defun erc-autojoin-add (proc parsed) - "Add the channel being joined to `erc-autojoin-channels-alist'." - (erc-autojoin--mutate proc parsed nil) - ;; 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'." - (erc-autojoin--mutate proc parsed 'remove) - ;; We must return nil to tell ERC to continue running the other - ;; functions. - nil) - -(provide 'erc-join) - -;;; erc-join.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-lang.el b/lisp/erc/erc-lang.el deleted file mode 100644 index 8c081b333d9..00000000000 --- a/lisp/erc/erc-lang.el +++ /dev/null @@ -1,211 +0,0 @@ -;;; erc-lang.el --- provide the LANG command to ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2002, 2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Alex Schroeder -;; Maintainer: Amin Bandali , F. Jason Park -;; Old-Version: 1.0.0 -;; URL: https://www.emacswiki.org/emacs/ErcLang -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This provides two commands: `language' is for everyday use, and -;; `erc-cmd-LANG' provides the /LANG command to ERC. - -;;; Code: - -(require 'erc) - -(define-obsolete-variable-alias 'iso-638-languages 'iso-639-1-languages "29.1") -(defvar iso-639-1-languages - '(("aa" . "Afar") - ("ab" . "Abkhazian") - ("af" . "Afrikaans") - ("am" . "Amharic") - ("ar" . "Arabic") - ("as" . "Assamese") - ("ay" . "Aymara") - ("az" . "Azerbaijani") - ("ba" . "Bashkir") - ("be" . "Belarusian") - ("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 - -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-639-1-languages))) - (message "%s" (cdr (assoc code iso-639-1-languages)))) - -(defun erc-cmd-LANG (language) - "Display the language name for the language code given by LANGUAGE." - (let ((lang (cdr (assoc language iso-639-1-languages)))) - (erc-display-message - nil 'notice 'active - (or lang (concat language ": No such domain")))) - t) - -(provide 'erc-lang) - -;;; erc-lang.el ends here diff --git a/lisp/erc/erc-list.el b/lisp/erc/erc-list.el deleted file mode 100644 index a715a35b82b..00000000000 --- a/lisp/erc/erc-list.el +++ /dev/null @@ -1,230 +0,0 @@ -;;; erc-list.el --- /list support for ERC -*- lexical-binding:t -*- - -;; Copyright (C) 2008-2025 Free Software Foundation, Inc. - -;; Author: Tom Tromey -;; Maintainer: Amin Bandali , F. Jason Park -;; Old-Version: 0.1 -;; URL: https://www.emacswiki.org/emacs/ErcList -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file provides nice support for /list in ERC. - -;;; Code: - -(require 'erc) - -(defgroup erc-list nil - "Support for the /list command." - :group 'erc) - -;; This is implicitly the width of the channel name column. Pick -;; something small enough that the topic has a chance of being -;; readable, but long enough that most channel names won't make for -;; strange formatting. -(defconst erc-list-nusers-column 25) - -;; Width of the number-of-users column. -(defconst erc-list-topic-column (+ erc-list-nusers-column 10)) - -;; The list buffer. This is buffer local in the server buffer. -(defvar erc-list-buffer nil) - -;; The argument to the last "/list". This is buffer local in the -;; server buffer. -(defvar erc-list-last-argument nil) - -;; The server buffer corresponding to the list buffer. This is buffer -;; local in the list buffer. -(defvar erc-list-server-buffer nil) - -;; Define module: -;;;###autoload(autoload 'erc-list-mode "erc-list") -(define-erc-module list nil - "List channels nicely in a separate buffer." - ((remove-hook 'erc-server-321-functions #'erc-server-321-message) - (remove-hook 'erc-server-322-functions #'erc-server-322-message)) - ((erc-with-all-buffers-of-server nil - #'erc-open-server-buffer-p - (remove-hook 'erc-server-322-functions #'erc-list-handle-322 t)) - (add-hook 'erc-server-321-functions #'erc-server-321-message t) - (add-hook 'erc-server-322-functions #'erc-server-322-message t))) - -;; Format a record for display. -(defun erc-list-make-string (channel users topic) - (concat - channel - (propertize " " - 'display (list 'space :align-to erc-list-nusers-column) - 'face 'fixed-pitch) - users - (propertize " " - 'display (list 'space :align-to erc-list-topic-column) - 'face 'fixed-pitch) - topic)) - -;; Insert a record into the list buffer. -(defun erc-list-insert-item (channel users topic) - (save-excursion - (let ((buffer-read-only nil)) - (goto-char (point-max)) - (insert (erc-list-make-string channel users topic) "\n")))) - -(defun erc-list-join () - "Join the irc channel named on this line." - (interactive) - (unless (eobp) - (beginning-of-line) - (unless (looking-at "\\([&#+!][^ \n]+\\)") - (error "Not looking at channel name?")) - (let ((chan (match-string 1))) - (with-current-buffer erc-list-server-buffer - (erc-join-channel chan))))) - -(defun erc-list-kill () - "Kill the current ERC list buffer." - (interactive) - (kill-buffer (current-buffer))) - -(defun erc-list-revert () - "Refresh the list of channels." - (interactive) - (with-current-buffer erc-list-server-buffer - (erc-cmd-LIST erc-list-last-argument))) - -(defun erc-list-menu-sort-by-column (&optional e) - "Sort the channel list by the column clicked on." - (interactive (list last-input-event)) - (if e (mouse-select-window e)) - (let* ((pos (event-start e)) - (obj (posn-object pos)) - (col (if obj - (get-text-property (cdr obj) 'column-number (car obj)) - (get-text-property (posn-point pos) 'column-number)))) - (let ((buffer-read-only nil)) - (if (= col 1) - (sort-fields col (point-min) (point-max)) - (sort-numeric-fields col (point-min) (point-max)))))) - -(defvar erc-list-menu-mode-map - (let ((map (make-keymap))) - (set-keymap-parent map special-mode-map) - (define-key map "k" #'erc-list-kill) - (define-key map "j" #'erc-list-join) - (define-key map "g" #'erc-list-revert) - (define-key map "n" #'next-line) - (define-key map "p" #'previous-line) - map) - "Local keymap for `erc-list-mode' buffers.") - -(defvar erc-list-menu-sort-button-map - (let ((map (make-sparse-keymap))) - (define-key map [header-line mouse-1] #'erc-list-menu-sort-by-column) - (define-key map [follow-link] 'mouse-face) - map) - "Local keymap for ERC list menu mode sorting buttons.") - -;; Helper function that makes a buttonized column header. -(defun erc-list-button (title column) - (propertize title - 'column-number column - 'help-echo "mouse-1: sort by column" - 'mouse-face 'header-line-highlight - 'keymap erc-list-menu-sort-button-map)) - -(define-derived-mode erc-list-menu-mode special-mode "ERC-List" - "Major mode for editing a list of irc channels." - (setq header-line-format - (concat - (propertize " " - 'display '(space :align-to 0) - 'face 'fixed-pitch) - (erc-list-make-string (erc-list-button "Channel" 1) - (erc-list-button "# Users" 2) - "Topic"))) - (setq truncate-lines t)) - -(put 'erc-list-menu-mode 'mode-class 'special) - -;; Handle a "322" response. This response tells us about a single -;; channel. -;; Called via erc-once-with-server-event with two arguments. -(defun erc-list-handle-322 (_proc parsed) - (let* ((args (cdr (erc-response.command-args parsed))) - (channel (car args)) - (nusers (car (cdr args))) - (topic (erc-response.contents parsed))) - (when (buffer-live-p erc-list-buffer) - (with-current-buffer erc-list-buffer - (erc-list-insert-item channel nusers topic)))) - ;; Don't let another hook run. - t) - -;; Helper function to install our 322 handler and make our buffer. -(defun erc-list-install-322-handler (server-buffer) - (with-current-buffer server-buffer - ;; Arrange for 322 responses to insert into our buffer. - (add-hook 'erc-server-322-functions #'erc-list-handle-322 t t) - ;; Arrange for 323 (end of list) to end this. - (erc-once-with-server-event - 323 - (lambda (_proc _parsed) - (remove-hook 'erc-server-322-functions #'erc-list-handle-322 t))) - ;; Find the list buffer, empty it, and display it. - (setq-local erc-list-buffer - (get-buffer-create (concat "*Channels of " - erc-server-announced-name - "*"))) - (with-current-buffer erc-list-buffer - (erc-list-menu-mode) - (setq buffer-read-only nil) - (erase-buffer) - (setq-local erc-list-server-buffer server-buffer) - (setq buffer-read-only t)) - (pop-to-buffer erc-list-buffer)) - t) - -;; The main entry point. -(defun erc-cmd-LIST (&optional line) - "Show a listing of channels on the current server in a separate window. - -If LINE is specified, include it with the /LIST command. It -should usually be one or more channels, separated by commas. - -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." - (erc-with-server-buffer - (setq-local erc-list-last-argument line) - (erc-once-with-server-event - 321 - (let ((buf (current-buffer))) - (lambda (_proc _parsed) - (erc-list-install-322-handler buf))))) - (erc-server-send (concat "LIST :" (or (and line (substring line 1)) - "")))) -(put 'erc-cmd-LIST 'do-not-parse-args t) - -(provide 'erc-list) - -;;; erc-list.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-log.el b/lisp/erc/erc-log.el deleted file mode 100644 index 730faacdfb3..00000000000 --- a/lisp/erc/erc-log.el +++ /dev/null @@ -1,466 +0,0 @@ -;;; erc-log.el --- Logging facilities for ERC. -*- lexical-binding: t; -*- - -;; Copyright (C) 2003-2025 Free Software Foundation, Inc. - -;; Author: Lawrence Mitchell -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcLogging -;; Keywords: comm, 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file implements log file writing support for ERC. - -;; Quick start: -;; -;; (require 'erc-log) -;; (setq erc-log-channels-directory "/path/to/logfiles") ; must be writable -;; (erc-log-enable) -;; -;; Or: -;; -;; M-x customize-variable erc-modules, and add "log". -;; -;; There are two ways to setup logging. The first (default) method -;; will save buffers on /part, /quit, or killing the channel -;; buffer. -;; -;; The second will write to the log files on each incoming or outgoing -;; line - this may not be optimal on a laptop HDD. To use this -;; method, add the following to the above instructions. -;; -;; (setq erc-save-buffer-on-part nil -;; erc-save-queries-on-quit nil -;; erc-log-write-after-send t -;; erc-log-write-after-insert t) -;; -;; If you only want to save logs for some buffers, customize 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: -;; -;; * 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 'erc-networks)) - -(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 that were used to connect to BUFFERs -`erc-server-process'. - -If you want to write logs into different directories, make a -custom function which returns the directory part and set -`erc-log-channels-directory' to its name." - :type '(choice (const :tag "#channel!nick@server:port.txt" - erc-generate-log-file-name-long) - (const :tag "#channel!nick@network.txt" - erc-generate-log-file-name-network) - (const :tag "#channel.txt" erc-generate-log-file-name-short) - (const :tag "#channel@date.txt" - erc-generate-log-file-name-with-date) - (function :tag "Other function"))) - -(defcustom erc-truncate-buffer-on-save nil - "Erase the contents of any ERC (channel, query, server) buffer when it is saved." - :type 'boolean) -(make-obsolete-variable 'erc-truncate-buffer-on-save - "maybe see command `erc-cmd-CLEAR'" "30.1") - -(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'." - :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. - -If this is the name of a function, the function will be called -with the buffer, target, nick, server, and port arguments. See -`erc-generate-log-file-name-function' for a description of these -arguments." - :type '(choice directory - (function "Function") - (const :tag "Disable logging" nil))) - -(defcustom erc-log-insert-log-on-open nil - "Insert log file contents into the buffer if a log file exists." - :type 'boolean) - -(defcustom erc-save-buffer-on-part t - "Save the channel buffer content using `erc-save-buffer-in-logs' on PART. - -If you set this to nil, you may want to enable both -`erc-log-write-after-send' and `erc-log-write-after-insert'." - :type 'boolean) - -(defcustom erc-save-queries-on-quit t - "Save all query (also channel) buffers of the server on QUIT. - -If you set this to nil, you may want to enable both -`erc-log-write-after-send' and `erc-log-write-after-insert'." - :type 'boolean) - -(defcustom erc-log-write-after-send nil - "If non-nil, write to log file after every message you send. - -If you set this to nil, you may want to enable both -`erc-save-buffer-on-part' and `erc-save-queries-on-quit'." - :type 'boolean) - -(defcustom erc-log-write-after-insert nil - "If non-nil, write to log file when new text is added to a logged ERC buffer. - -If you set this to nil, you may want to enable both -`erc-save-buffer-on-part' and `erc-save-queries-on-quit'." - :type 'boolean) - -(defcustom erc-log-file-coding-system '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'." - :type 'coding-system) - -(defcustom erc-log-filter-function nil - "If non-nil, pass text to this function before writing it to a log file. - -The function should take one argument, which is the text to filter." - :type '(choice (function "Function") - (function-item erc-stamp-prefix-log-filter) - (const :tag "No filtering" nil))) - - -;;;###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 -behavior 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 - (null (erc-away-time)))))" - ;; enable - ((when erc-log-write-after-insert - (add-hook 'erc-insert-post-hook #'erc-save-buffer-in-logs)) - (when erc-log-write-after-send - (add-hook 'erc-send-post-hook #'erc-save-buffer-in-logs)) - (add-hook 'erc-kill-buffer-hook #'erc-save-buffer-in-logs) - (add-hook 'erc-kill-channel-hook #'erc-save-buffer-in-logs) - (add-hook 'kill-emacs-hook #'erc-log-save-all-buffers) - (add-hook 'erc-quit-hook #'erc-conditional-save-queries) - (add-hook 'erc-part-hook #'erc-conditional-save-buffer) - ;; append, so that 'erc-initialize-log-marker runs first - (add-hook 'erc-connect-pre-hook #'erc-log-setup-logging 'append) - (add-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs 50) - (dolist (buffer (erc-buffer-list)) - (erc-log-setup-logging buffer)) - (erc--modify-local-map t "C-c C-l" #'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) - (remove-hook 'erc-kill-buffer-hook #'erc-save-buffer-in-logs) - (remove-hook 'erc-kill-channel-hook #'erc-save-buffer-in-logs) - (remove-hook 'kill-emacs-hook #'erc-log-save-all-buffers) - (remove-hook 'erc-quit-hook #'erc-conditional-save-queries) - (remove-hook 'erc-part-hook #'erc-conditional-save-buffer) - (remove-hook 'erc-connect-pre-hook #'erc-log-setup-logging) - (remove-hook 'erc--pre-clear-functions #'erc-save-buffer-in-logs) - (dolist (buffer (erc-buffer-list)) - (erc-log-disable-logging buffer)) - (erc--modify-local-map nil "C-c C-l" #'erc-save-buffer-in-logs))) - -;;; functionality referenced from erc.el -(defun erc-log-setup-logging (buffer) - "Setup the buffer-local logging variables in the current buffer. -This function is destined to be run from `erc-connect-pre-hook'. -The current buffer is given by BUFFER." - (when (erc-logging-enabled buffer) - (with-current-buffer buffer - (auto-save-mode -1) - (setq buffer-file-name nil) - (add-hook 'write-file-functions #'erc-save-buffer-in-logs nil t) - (when erc-log-insert-log-on-open - (ignore-errors - (save-excursion - (goto-char (point-min)) - (insert-file-contents (erc-current-logfile))) - (move-marker erc-last-saved-position - (1- (point-max)))))))) - -(defun erc-log-disable-logging (buffer) - "Disable logging in BUFFER." - (when (erc-logging-enabled buffer) - (with-current-buffer buffer - (setq buffer-offer-save nil - erc-enable-logging nil)))) - -(defun erc-log-all-but-server-buffers (buffer) - "Return t if logging should be enabled in BUFFER. -Return nil if BUFFER is a server buffer." - (save-excursion - (save-window-excursion - (set-buffer buffer) - (not (erc--server-buffer-p))))) - -(defun erc-save-query-buffers (process) - "Save all buffers of the given PROCESS." - (erc-with-all-buffers-of-server process - nil - (erc-save-buffer-in-logs))) - -(defun erc-conditional-save-buffer (buffer) - "Save channel BUFFER if it and `erc-save-buffer-on-part' are non-nil." - (when (and buffer 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))) - -;; Make sure that logs get saved, even if someone overrides the active -;; process prompt for a quick exit from Emacs -(defun erc-log-save-all-buffers () - (dolist (buffer (erc-buffer-list)) - (erc-save-buffer-in-logs buffer))) - -(defvar erc-log--save-in-progress-p nil) - -;;;###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 writable (it will be created as necessary) and -`erc-enable-logging' returns a non-nil value." - (or buffer (setq buffer (current-buffer))) - (and erc-log-channels-directory - (not erc-log--save-in-progress-p) - (not (erc--memq-msg-prop 'erc--skip 'log)) - (or (functionp erc-log-channels-directory) - (erc-directory-writable-p erc-log-channels-directory)) - (if (functionp erc-enable-logging) - (funcall erc-enable-logging buffer) - (buffer-local-value 'erc-enable-logging buffer)))) - -(defun erc-log-standardize-name (filename) - "Make FILENAME safe to use as the name of an ERC log. -This will not work with full paths, only names. - -Any unsafe characters in the name are replaced with \"!\". The -filename is downcased." - (downcase (replace-regexp-in-string - "[/\\]" "!" (convert-standard-filename filename)))) - -(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." - (unless buffer (setq buffer (current-buffer))) - (with-current-buffer buffer - (let ((target (or (buffer-name buffer) (erc-default-target))) - (nick (erc-current-nick)) - (server erc-session-server) - (port erc-session-port)) - (expand-file-name - (erc-log-standardize-name - (funcall erc-generate-log-file-name-function - buffer target nick server port)) - (if (functionp erc-log-channels-directory) - (funcall erc-log-channels-directory - buffer target nick server port) - erc-log-channels-directory))))) - -(defun erc-generate-log-file-name-with-date (buffer &rest _ignore) - "Return a short log file name with the current date. -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) - "Return 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) - "Generate 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))) - -(declare-function erc-network-name "erc-networks" ()) - -(defun erc-generate-log-file-name-network (buffer target nick server _port) - "Generate a log-file name using the network name rather than server name. -This results in a file name of the form #channel!nick@network.txt. -This function is a possible value for `erc-generate-log-file-name-function'." - (require 'erc-networks) - (let ((file (concat - (if target (concat target "!")) - nick "@" - (or (with-current-buffer buffer (erc-network-name)) server) - ".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) - (unless (bufferp buffer) (setq buffer (current-buffer))) - (when (erc-logging-enabled buffer) - (let ((file (erc-current-logfile buffer)) - (coding-system erc-log-file-coding-system)) - (save-excursion - (with-current-buffer buffer - (save-restriction - (widen) - ;; early on in the initialization, don't try and write the log out - (when (and (markerp erc-last-saved-position) - (> erc-insert-marker (1+ erc-last-saved-position))) - (let ((start (1+ (marker-position erc-last-saved-position))) - (end (marker-position erc-insert-marker))) - (if (functionp erc-log-filter-function) - (let ((text (buffer-substring start end))) - (with-temp-buffer - (insert (funcall erc-log-filter-function text)) - (let ((coding-system-for-write coding-system)) - (write-region (point-min) (point-max) - file t 'nomessage)))) - (let ((coding-system-for-write coding-system)) - (write-region start end file t 'nomessage)))) - (if (and erc-truncate-buffer-on-save - (called-interactively-p 'interactive)) - (let ((erc-log--save-in-progress-p t)) - (save-excursion (goto-char erc-insert-marker) - (erc-cmd-CLEAR)) - (erc-button--display-error-notice-with-keys - (erc-server-buffer) "Option `%s' is deprecated." - " Use /CLEAR instead." 'erc-truncate-buffer-on-save)) - (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) - -;; This is a kludge to avoid littering erc-truncate.el with forward -;; declarations needed only for a corner-case compatibility check. -(defun erc-log--call-when-logging-enabled-sans-module (fn) - (when (and (erc-logging-enabled) - (not (or erc-log-mode (memq 'log erc-modules)))) - (let ((dirfile (and (stringp erc-log-channels-directory) - erc-log-channels-directory))) - (funcall fn dirfile)))) - -(provide 'erc-log) - -;;; erc-log.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el deleted file mode 100644 index ffb5a2af91e..00000000000 --- a/lisp/erc/erc-match.el +++ /dev/null @@ -1,715 +0,0 @@ -;;; erc-match.el --- Highlight messages matching certain regexps -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2025 Free Software Foundation, Inc. - -;; Author: Andreas Fuchs -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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 init file. - -;;; Code: - -(require 'erc) - -;; Customization: - -(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 50) - (add-hook 'erc-mode-hook #'erc-match--setup) - (unless erc--updating-modules-p (erc-buffer-do #'erc-match--setup)) - (add-hook 'erc-insert-post-hook #'erc-match--on-insert-post 50) - (erc--modify-local-map t "C-c C-k" #'erc-go-to-log-matches-buffer)) - ((remove-hook 'erc-insert-modify-hook #'erc-match-message) - (remove-hook 'erc-insert-post-hook #'erc-match--on-insert-post) - (remove-hook 'erc-mode-hook #'erc-match--setup) - (erc-buffer-do #'erc-match--setup) - (erc--modify-local-map nil "C-c C-k" #'erc-go-to-log-matches-buffer))) - -;; Remaining customizations - -(defcustom erc-pals nil - "List of pals on IRC." - :type '(repeat regexp)) - -(defcustom erc-fools nil - "List of fools on IRC." - :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." - :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." - :type '(repeat regexp)) - -(defcustom erc-current-nick-highlight-type 'keyword - "Determine 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 - `message' - highlight the entire message where current nickname occurs - `all' - highlight the entire message (including the nick) where - current nickname occurs - -Any other value disables highlighting of current nickname altogether." - :type '(choice (const nil) - (const nick) - (const keyword) - (const nick-or-keyword) - (const message) - (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 - \\+`message' - highlight the full message body from a matching pal - `all' - highlight the entire message (including the nick) - from pal - -A value of `nick' only highlights a matching sender's nick in the -bracketed speaker portion of the message. A value of \\+`message' -basically highlights its complement: the message-body alone, after the -speaker tag. All values for this option require a matching sender to be -an actual user on the network \(or a bot/service) as opposed to a host -name, such as that of the server itself \(e.g. \"irc.gnu.org\"). When -patterns from other user-based categories \(namely, \\+`fool' and -\\+`dangerous-host') also match, the behavior is undefined. However, in -ERC 5.6, `erc-dangerous-host-face' is known to clobber `erc-fool-face', -which in turn clobbers `erc-pal-face'. \(Other effects, such as -\\+`fool'-related invisibility may not survive such collisions.)" - :type '(choice (const nil) - (const nick) - (const message) - (const all))) - -(defcustom erc-fool-highlight-type 'nick - "Determines how to highlight messages by fools. -Unlike with the \\+`pal' and \\+`dangerous-host' categories, ERC doesn't -only attempt to match associated patterns (here, from `erc-fools') -against a message's sender, it also checks for matches in traditional -IRC-style \"mentions\" in which a speaker addresses a USER directly: - - USER: hi. - USER, hi. - -However, at present, this option doesn't offer a means of highlighting -matched mentions alone. See `erc-pal-highlight-type' for a summary of -possible values and additional details common to categories like -\\+`fool' that normally match against a message's sender." - :type '(choice (const nil) - (const nick) - (const message) - (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 - `message' - highlight the entire message containing keyword - `all' - highlight the entire message (including the nick) - containing keyword - -Any other value disables keyword highlighting altogether." - :type '(choice (const nil) - (const keyword) - (const message) - (const all))) - -(defcustom erc-dangerous-host-highlight-type 'nick - "Determines how to highlight messages by nicks from dangerous-hosts. -Use option `erc-dangerous-hosts' to specify patterns. See -`erc-pal-highlight-type' for a summary of possible values as well as -additional details common to categories like \\+`dangerous-host' that -normally match against a message's sender." - :type '(choice (const nil) - (const nick) - (const message) - (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." - :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." - :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" - :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." - :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) - "Abnormal hook for visiting text matching a predefined \"type\". -ERC calls members with the arguments (MATCH-TYPE NUH MESSAGE), where -MATCH-TYPE is a symbol among `current-nick', `keyword', `pal', -`dangerous-host', and `fool'; and NUH is an `erc-response' sender, like -\"bob!~bob@example.org\" or an IRC command prefixed with the string -\"Server:\", as in \"Server:353\". MESSAGE is the current incarnation -of the just-inserted message minus a leading speaker, like \" \". -For traditional reasons, MESSAGE always includes a leading -`erc-notice-prefix' and a trailing newline." - :options '(erc-log-matches erc-hide-fools erc-beep-on-match) - :type 'hook) - -(defcustom erc-match-exclude-server-buffer nil - "If true, don't perform match on the server buffer. -This is useful for excluding all the things like MOTDs from the -server and other miscellaneous functions." - :version "24.3" - :type 'boolean) - -(defcustom erc-match-quote-when-adding 'ask - "Whether to `regexp-quote' when adding to a match list interactively. -When the value is a boolean, the opposite behavior will be made -available via universal argument." - :package-version '(ERC . "5.5") - :type '(choice (const ask) - (const t) - (const nil))) - -;; 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) - table) - "Syntax table used when highlighting messages. -This syntax table should make all the valid nick characters word -constituents.") - -;; Faces: - -(defface erc-current-nick-face '((t :weight bold :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 :weight bold :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 :weight bold :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 alt) - "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)))))) - quoted) - (setq quoted (regexp-quote entry)) - (when (pcase erc-match-quote-when-adding - ('ask (unless (string= quoted entry) - (y-or-n-p - (format "Use regexp-quoted form (%s) instead? " quoted)))) - ('t (not alt)) - ('nil alt)) - (setq entry quoted)) - (if (erc-member-ignore-case entry (symbol-value list)) - (error "\"%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 (&optional arg) - "Add pal interactively to `erc-pals'." - (interactive "P") - (erc-add-entry-to-list 'erc-pals "Add pal: " - (erc-get-server-nickname-alist) arg)) - -;;;###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 (&optional arg) - "Add fool interactively to `erc-fools'." - (interactive "P") - (erc-add-entry-to-list 'erc-fools "Add fool: " - (erc-get-server-nickname-alist) arg)) - -;;;###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 (&optional arg) - "Add keyword interactively to `erc-keywords'." - (interactive "P") - (erc-add-entry-to-list 'erc-keywords "Add keyword: " nil arg)) - -;;;###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 (&optional arg) - "Add dangerous-host interactively to `erc-dangerous-hosts'." - (interactive "P") - (erc-add-entry-to-list 'erc-dangerous-hosts "Add dangerous-host: " nil arg)) - -;;;###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-pals - (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 erc-fools - (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-keywords - (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-dangerous-hosts - (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-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-beg (if (and nick-end - (<= (+ 2 nick-end) (point-max))) - ;; Message starts 2 characters after the - ;; nick except for CTCP ACTION messages. - ;; Nick surrounded by angle brackets only in - ;; normal messages. - (+ nick-end - (if (eq ?> (char-after nick-end)) - 2 - 1)) - (point-min))) - (message (buffer-substring message-beg (point-max)))) - (when (and vector - (not (and erc-match-exclude-server-buffer - ;; FIXME replace with `erc--server-buffer-p' - ;; or explain why that's unwise. - (erc-server-or-unjoined-channel-buffer-p)))) - (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 (symbol-value (intern (concat match-prefix - "-highlight-type")))) - (match-regex (if (string= match-type "current-nick") - (regexp-quote (erc-current-nick)) - (symbol-value - (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 - 'font-lock-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 - 'font-lock-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) - 'font-lock-face match-face)))) - ;; Highlight the whole message (not including the nick) - ((eq match-htype 'message) - (erc-put-text-property - message-beg (point-max) - 'font-lock-face match-face (current-buffer))) - ;; Highlight the whole message (including the nick) - ((eq match-htype 'all) - (erc-put-text-property - (point-min) (point-max) - 'font-lock-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) - 'font-lock-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) - 'font-lock-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 behavior 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-time))) - match-buffer-name) - (let ((line (format-spec - erc-log-match-format - `((?n . ,nick) - (?t . ,(format-time-string - (or (bound-and-true-p 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) - (let ((inhibit-read-only t)) - (goto-char (point-max)) - (insert line))))))) - -(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") - (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-time) - (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-time)))) - (when (and away-time last-msg-time - (time-less-p away-time last-msg-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))) - -(defun erc-hide-fools (match-type _nickuserhost _message) - "Hide comments from designated fools." - (when (and erc--msg-props (eq match-type 'fool)) - (puthash 'erc--invisible 'erc-match-fool erc--msg-props))) - -;; FIXME remove, make public, or only add locally. -;; -;; ERC modules typically don't add internal functions to public hooks -;; globally. However, ERC 5.6 will likely include a general -;; (internal) facility for adding invisible props, which will obviate -;; the need for this function. IOW, leaving this internal for now is -;; an attempt to avoid the hassle of the deprecation process. -(defun erc-match--on-insert-post () - "Hide messages marked with the `erc--invisible' prop." - (when (erc--check-msg-prop 'erc--invisible 'erc-match-fool) - (remhash 'erc--invisible erc--msg-props) - (erc--hide-message 'match-fools))) - -(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))) - -(defun erc-match--setup () - "Add an `erc-match' property to the local spec." - ;; Hopefully, this will be extended to do the same for other - ;; invisible properties managed by this module. - (if erc-match-mode - (erc-match-toggle-hidden-fools +1) - (erc-match-toggle-hidden-fools -1))) - -(defun erc-match-toggle-hidden-fools (arg) - "Toggle fool visibility. -Expect the function `erc-hide-fools' or similar to be present in -`erc-text-matched-hook'." - (interactive "P") - (erc--toggle-hidden 'match-fools arg)) - -(provide 'erc-match) - -;;; erc-match.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-menu.el b/lisp/erc/erc-menu.el deleted file mode 100644 index 7341eb1b3b3..00000000000 --- a/lisp/erc/erc-menu.el +++ /dev/null @@ -1,135 +0,0 @@ -;;; erc-menu.el --- Menu-bar definitions for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2002, 2004-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, menu - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; Loading this file defines a menu for ERC. - -;;; Code: - -(require 'erc) - -(defgroup erc-menu nil - "ERC menu support." - :group 'erc) - -(defvar erc-menu-definition - (list "ERC" - ["Connect to server..." erc t] - ["Disconnect from server..." erc-quit-server erc-server-connected] - "-" - ["List channels..." erc-list-channels - (and erc-server-connected (fboundp 'erc-list-channels))] - ["Join channel..." erc-join-channel erc-server-connected] - ["Start a query..." erc-cmd-QUERY erc-server-connected] - ["Input action..." erc-input-action (erc-default-target)] - "-" - (list - "Current channel" - ["List users in channel" erc-channel-names erc-channel-users] - ["List channel operators" erc-cmd-OPS erc-channel-users] - ["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.") - -(defvar erc-menu-defined nil - "Internal variable used to keep track of whether we've defined the ERC menu yet.") - -;;;###autoload(autoload 'erc-menu-mode "erc-menu" nil t) -(define-erc-module menu nil - "Enable a menu in ERC buffers." - ((unless erc-menu-defined - ;; make sure the menu only gets defined once, since Emacs - ;; activates it immediately - (easy-menu-define erc-menu erc-mode-map "ERC menu" erc-menu-definition) - (setq erc-menu-defined t))) - (;; `easy-menu-remove' is a no-op in Emacs - (message "You might have to restart Emacs to remove the ERC menu"))) - -(defun erc-menu-add () - "Add the ERC menu to the current buffer." - (declare (obsolete nil "28.1")) - nil) - -(defun erc-menu-remove () - "Remove the ERC menu from the current buffer." - (declare (obsolete nil "28.1")) - nil) - -(provide 'erc-menu) - -;;; erc-menu.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-netsplit.el b/lisp/erc/erc-netsplit.el deleted file mode 100644 index d99ec67cca0..00000000000 --- a/lisp/erc/erc-netsplit.el +++ /dev/null @@ -1,214 +0,0 @@ -;;; erc-netsplit.el --- Reduce JOIN/QUIT messages on netsplits -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This module hides quit/join messages if a netsplit occurs. -;; To enable, add the following to your init file: -;; (require 'erc-netsplit) -;; (erc-netsplit-mode 1) - -;;; Code: - -(require 'erc) - -(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." - ( ; FIXME delete newline on next edit - (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 - "Non-nil means to enable display of server mode changes." - :type 'boolean) - -(defcustom erc-netsplit-debug nil - "If non-nil, debug messages will be shown in the sever buffer." - :type 'boolean) - -(defcustom erc-netsplit-regexp - "^[^ @!\"\n]+\\.[^ @!\n]+ [^ @!\n]+\\.[^ @!\"\n]+$" - "This regular expression should match quit reasons produced by netsplits." - :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-local 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.") - -(defun erc-netsplit-install-message-catalogs () - (declare (obsolete "defined at top level in erc-netsplit.el" "30.1")) - (with-suppressed-warnings ((obsolete erc-define-catalog)) ; indentation - (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"))))) ; indentation - -(erc-define-message-format-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 (nth 2 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))) - ;; Avoid `ignored-return-value' warning for `delete'. - (let ((tail (nthcdr 2 elt))) ; (t n1 ... nN) - (setcdr tail (delete nick (cdr tail))))) - (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 "^[^@!\n]+\\.[^@!\n]+$" (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 (nth 2 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." - (when erc-server-connected - (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." - (erc-with-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 (nth 2 elt) - "(joining)" - ""))))) - t) - -(defalias 'erc-cmd-WL #'erc-cmd-WHOLEFT) - -(provide 'erc-netsplit) - -;;; erc-netsplit.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el deleted file mode 100644 index 9836628fb61..00000000000 --- a/lisp/erc/erc-networks.el +++ /dev/null @@ -1,1667 +0,0 @@ -;;; erc-networks.el --- IRC networks -*- lexical-binding: t; -*- - -;; Copyright (C) 2002, 2004-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file deals with IRC networks. -;; -;; Usage: -;; -;; This is the "networks" module. -;; -;; 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: - -(eval-when-compile (require 'cl-lib)) -(require 'erc-common) - -(defvar erc--target) -(defvar erc-insert-marker) -(defvar erc-modules) -(defvar erc-rename-buffers) -(defvar erc-reuse-buffers) -(defvar erc-server-announced-name) -(defvar erc-server-connected) -(defvar erc-server-process) - -(declare-function erc--get-isupport-entry "erc-backend" (key &optional single)) -(declare-function erc--insert-admin-message "erc" (&rest args)) -(declare-function erc-buffer-filter "erc" (predicate &optional proc)) -(declare-function erc-current-nick "erc" nil) -(declare-function erc-display-error-notice "erc" (parsed string)) -(declare-function erc-display-message "erc" (parsed type buffer msg &rest args)) -(declare-function erc-get-buffer "erc" (target &optional proc)) -(declare-function erc-server-process-alive "erc-backend" (&optional buffer)) -(declare-function erc-set-active-buffer "erc" (buffer)) - -(declare-function erc-button--display-error-notice-with-keys - (maybe-buffer &rest strings)) - -;; 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))) - ("Ars-OpenIRC: Random server" Ars "irc.arstechnica.com" 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, Gothenburg" 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 "chat.freenode.net" 6667) - ("Freenode: Random EU server" freenode "chat.eu.freenode.net" 6667) - ("Freenode: Random US server" freenode "chat.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))) - ;; This one is dead but used in testing. Please retain. - ("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) - ("Libera.Chat: Random server" Libera.Chat "irc.libera.chat" - ((6665 6667) (8000 8002)) (6697 7000 7070)) - ;; If not deprecating this option, use ^ for the rest of these servers. - ("Libera.Chat: Random Europe server" Libera.Chat "irc.eu.libera.chat" 6667 6697) - ("Libera.Chat: Random US & Canada server" Libera.Chat "irc.us.libera.chat" 6667 6697) - ("Libera.Chat: Random Australia & New Zealand server" Libera.Chat "irc.au.libera.chat" 6667 6697) - ("Libera.Chat: Random East Asia server" Libera.Chat "irc.ea.libera.chat" 6667 6697) - ("Libera.Chat: IPv4 only server" Libera.Chat "irc.ipv4.libera.chat" 6667 6697) - ("Libera.Chat: IPv6 only server" Libera.Chat "irc.ipv6.libera.chat" 6667 6697) - ("Librenet: Random server" Librenet "irc.librenet.net" 6667) - ("LinkNet: Random server" LinkNet "irc.link-net.org" ((6667 6669))) - ("LinuxChix: Random server" LinuxChix "irc.linuxchix.org" 6667) - ("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) - ("OFTC: Random server" OFTC "irc.oftc.net" ((6667 6670) 7000) (6697 9999)) - ("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))) - ("Rizon: Random server" Rizon "irc.rizon.net" (6633 (6660 6669) 6697 7000 8080 9999)) - ("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. -Each server is a list (NAME NET HOST PORTS TLS-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 server's hostname, and (TLS-)PORTS is either a -number, a list of numbers, or a list of port ranges." - :package-version '(ERC . "5.6") - :type '(alist :key-type (string :tag "Name") - :value-type - (group symbol (string :tag "Hostname") - (choice :tag "Ports" - (integer :tag "Port number") - (repeat :tag "List of ports or ranges" - (choice (integer :tag "Port number") - (list :tag "Port range" - integer integer)))) - (choice :tag "TLS ports" - (integer :tag "TLS port number") - (repeat :tag "List of TLS ports or ranges" - (choice (integer :tag "TLS port number") - (list :tag "TLS port range" - integer integer))))))) -(make-obsolete-variable 'erc-server-alist - "specify `:server' with `erc-tls'." "30.1") - -(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") - (Ars "arstechnica.com") - (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") - (Libera.Chat "libera.chat") - (Librenet "librenet.net") - (LinkNet "link-net.org") - (LinuxChix "cats\\.meow\\.at\\|linuxchix\\.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") - (OFTC "oftc.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. -Each network is a list (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 a regexp, it's used to match against -`erc-server-announced-name'." - :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-local erc-network nil - "The name of the network you are connected to (a symbol).") - - -;;;; Identifying session context - -;; This section is concerned with identifying and managing the -;; relationship between an IRC connection and its unique identity on a -;; given network (as seen by that network's nick-granting system). -;; This relationship is quasi-permanent and transcends IRC connections -;; and Emacs sessions. As of mid 2022, only nicknames matter, and -;; whether a user is authenticated does not directly impact network -;; identity from a client's perspective. However, ERC must be -;; equipped to adapt should this ever change. And while a connection -;; is normally associated with exactly one nick, some networks (or -;; intermediaries) may allow multiple clients to control the same nick -;; by combining instance activity into a single logical client. ERC -;; must be limber enough to handle such situations. - -(defvar-local erc-networks--id nil - "Server-local instance of its namesake struct. -Also shared among all target buffers for a given connection. See -\\[describe-symbol] `erc-networks--id' for more.") - -(cl-defstruct erc-networks--id - "Persistent identifying info for a network presence. - -Here, \"presence\" refers to some local state representing a -client's existence on a network. Some clients refer to this as a -\"context\" or a \"net-id\". The management of this state -involves tracking associated buffers and what they're displaying. -Since a presence can outlast physical connections and survive -changes in back-end transports (and even outlive Emacs sessions), -its identity must be resilient. - -Essential to this notion of an enduring existence on a network is -ensuring recovery from the loss of a server buffer. Thus, any -useful identifier must be shared among server and target buffers -to allow for reassociation. Beyond that, it must ideally be -derivable from the same set of connection parameters. See the -constructor `erc-networks--id-create' for more info." - (ts nil :type float :read-only t :documentation "Creation timestamp.") - (symbol nil :type symbol :documentation "ID as a symbol.")) - -(cl-defstruct (erc-networks--id-fixed - (:include erc-networks--id) - (:constructor erc-networks--id-fixed-create - (given &aux (ts (float-time)) (symbol given))))) - -(cl-defstruct (erc-networks--id-qualifying - (:include erc-networks--id) - (:constructor erc-networks--id-qualifying-create - (&aux - (ts (float-time)) - (parts (erc-networks--id-qualifying-init-parts)) - (symbol (erc-networks--id-qualifying-init-symbol - parts)) - (len 1)))) - "A session context composed of hierarchical connection parameters. -Two identifiers are considered equivalent when their non-empty -`parts' slots compare equal. Related identifiers share a common -prefix of `parts' taken from connection parameters (given or -discovered). An identifier's unique `symbol', intended for -display purposes, is created by concatenating the shortest common -prefix among its relatives. For example, related presences [b a -r d o] and [b a z a r] would have symbols b/a/r and b/a/z -respectively. The separator is given by `erc-networks--id-sep'." - (parts nil :type sequence ; a vector of atoms - :documentation "Sequence of identifying components.") - (len 0 :type integer - :documentation "Length of active `parts' interval.")) - -(define-inline erc-networks--id-string (id) - "Return the symbol for `erc-networks--id' ID as a string." - (inline-quote (symbol-name (erc-networks--id-symbol ,id)))) - -;; For now, please use this instead of `erc-networks--id-fixed-p'. -(cl-defgeneric erc-networks--id-given (net-id) - "Return the preassigned identifier for a network context, if any. -When non-nil, assume NET-ID originated from an `:id' argument to -entry-point commands `erc-tls' or `erc'.") - -(cl-defmethod erc-networks--id-given (_) nil) ; _ may be nil - -(cl-defmethod erc-networks--id-given ((nid erc-networks--id-fixed)) - (erc-networks--id-symbol nid)) - -(cl-generic-define-context-rewriter erc-obsolete-var (var spec) - `((with-suppressed-warnings ((obsolete ,var) (free-vars ,var)) ,var) ,spec)) - -;; As a catch-all, derive the symbol from the unquoted printed repr. -(cl-defgeneric erc-networks--id-create (id) - "Invoke an appropriate constructor for an `erc-networks--id' object." - (erc-networks--id-fixed-create (intern (format "%s" id)))) - -;; When a given ID is a symbol, trust it unequivocally. -(cl-defmethod erc-networks--id-create ((id symbol)) - (erc-networks--id-fixed-create id)) - -;; Otherwise, use an adaptive name derived from network params. -(cl-defmethod erc-networks--id-create ((_ null)) - (erc-networks--id-qualifying-create)) - -;; But honor an explicitly set `erc-rename-buffers' (compat). -(cl-defmethod erc-networks--id-create - ((_ null) &context (erc-obsolete-var erc-rename-buffers null)) - (erc-networks--id-fixed-create (intern (buffer-name)))) - -;; But honor an explicitly set `erc-reuse-buffers' (compat). -(cl-defmethod erc-networks--id-create - ((_ null) &context (erc-obsolete-var erc-reuse-buffers null)) - (erc-networks--id-fixed-create (intern (buffer-name)))) - -(cl-defmethod erc-networks--id-create - ((_ symbol) &context (erc-obsolete-var erc-reuse-buffers null)) - (erc-networks--id-fixed-create (intern (buffer-name)))) - -(cl-defgeneric erc-networks--id-equal-p (self other) - "Return non-nil when two network IDs exhibit underlying equality. -Expect SELF and OTHER to be `erc-networks--id' struct instances -and that this will only be called for ID recovery or merging, -after which no two identities should be `equal' (timestamps -aside) that aren't also `eq'.") - -(cl-defmethod erc-networks--id-equal-p ((_ null) (_ erc-networks--id)) nil) -(cl-defmethod erc-networks--id-equal-p ((_ erc-networks--id) (_ null)) nil) - -(cl-defmethod erc-networks--id-equal-p ((self erc-networks--id) - (other erc-networks--id)) - (eq self other)) - -(cl-defmethod erc-networks--id-equal-p ((a erc-networks--id-fixed) - (b erc-networks--id-fixed)) - (or (eq a b) (eq (erc-networks--id-symbol a) (erc-networks--id-symbol b)))) - -(cl-defmethod erc-networks--id-equal-p ((a erc-networks--id-qualifying) - (b erc-networks--id-qualifying)) - (or (eq a b) (equal (erc-networks--id-qualifying-parts a) - (erc-networks--id-qualifying-parts b)))) - -;; ERASE-ME: if some future extension were to come along offering -;; additional members, e.g., [Libera.Chat "bob" laptop], it'd likely -;; be cleaner to create a new struct type descending from -;; `erc-networks--id-qualifying' than to convert this function into a -;; generic. However, the latter would be simpler because it'd just -;; require something like &context (erc-v3-device erc-v3--device-t). - -(defun erc-networks--id-qualifying-init-parts () - "Return opaque list of atoms to serve as canonical identifier." - (when-let ((network (erc-network)) - (nick (erc-current-nick))) - (vector network (erc-downcase nick)))) - -(defvar erc-networks--id-sep "/" - "Separator for joining `erc-networks--id-qualifying-parts' into a net ID.") - -(defun erc-networks--id-qualifying-init-symbol (elts &optional len) - "Return symbol appropriate for network context identified by ELTS. -Use leading interval of length LEN as contributing components. -Combine them with string separator `erc-networks--id-sep'." - (when elts - (unless len - (setq len 1)) - (intern (mapconcat (lambda (s) (prin1-to-string s t)) - (seq-subseq elts 0 len) - erc-networks--id-sep)))) - -(defun erc-networks--id-qualifying-grow-id (nid) - "Grow NID by one component or return nil when at capacity." - (unless (= (length (erc-networks--id-qualifying-parts nid)) - (erc-networks--id-qualifying-len nid)) - (setf (erc-networks--id-symbol nid) - (erc-networks--id-qualifying-init-symbol - (erc-networks--id-qualifying-parts nid) - (cl-incf (erc-networks--id-qualifying-len nid)))))) - -(defun erc-networks--id-qualifying-reset-id (nid) - "Restore NID to its initial state." - (setf (erc-networks--id-qualifying-len nid) 1 - (erc-networks--id-symbol nid) - (erc-networks--id-qualifying-init-symbol - (erc-networks--id-qualifying-parts nid)))) - -(defun erc-networks--id-qualifying-prefix-length (nid-a nid-b) - "Return length of common initial prefix of NID-A and NID-B. -Return nil when no such sequence exists (instead of zero)." - (when-let* ((a (erc-networks--id-qualifying-parts nid-a)) - (b (erc-networks--id-qualifying-parts nid-b)) - (n (min (length a) (length b))) - ((> n 0)) - ((equal (elt a 0) (elt b 0))) - (i 1)) - (while (and (< i n) - (equal (elt a i) - (elt b i))) - (cl-incf i)) - i)) - -(defun erc-networks--id-qualifying-update (dest source &rest overrides) - "Update DEST from SOURCE in place. -Copy slots into DEST from SOURCE and recompute ID. Both SOURCE -and DEST must be `erc-networks--id' objects. OVERRIDES is an -optional plist of SLOT VAL pairs." - (setf (erc-networks--id-qualifying-parts dest) - (or (plist-get overrides :parts) - (erc-networks--id-qualifying-parts source)) - (erc-networks--id-qualifying-len dest) - (or (plist-get overrides :len) - (erc-networks--id-qualifying-len source)) - (erc-networks--id-symbol dest) - (or (plist-get overrides :symbol) - (erc-networks--id-qualifying-init-symbol - (erc-networks--id-qualifying-parts dest) - (erc-networks--id-qualifying-len dest))))) - -(cl-defgeneric erc-networks--id-reload (_nid &optional _proc _parsed) - "Handle an update to the current network identity. -If provided, PROC should be the current `erc-server-process' and -PARSED the current `erc-response'. NID is an `erc-networks--id' -object." - nil) - -(cl-defmethod erc-networks--id-reload ((nid erc-networks--id-qualifying) - &optional proc parsed) - "Refresh identity after an `erc-networks--id-qualifying-parts'update." - (erc-networks--id-qualifying-update nid (erc-networks--id-qualifying-create) - :len - (erc-networks--id-qualifying-len nid)) - (erc-networks--rename-server-buffer (or proc erc-server-process) parsed) - (erc-networks--shrink-ids-and-buffer-names-any) - (erc-with-all-buffers-of-server erc-server-process #'erc-target - (when-let - ((new-name (erc-networks--reconcile-buffer-names erc--target nid)) - ((not (equal (buffer-name) new-name)))) - (rename-buffer new-name 'unique)))) - -(cl-defgeneric erc-networks--id-ensure-comparable (self other) - "Take measures to ensure two net identities are in comparable states.") - -(cl-defmethod erc-networks--id-ensure-comparable ((_ erc-networks--id) - (_ erc-networks--id)) - nil) - -(cl-defmethod erc-networks--id-ensure-comparable - ((nid erc-networks--id-qualifying) (other erc-networks--id-qualifying)) - "Grow NID along with that of the current buffer. -Rename the current buffer if its NID has grown." - (when-let ((n (erc-networks--id-qualifying-prefix-length other nid))) - (while (and (<= (erc-networks--id-qualifying-len nid) n) - (erc-networks--id-qualifying-grow-id nid))) - ;; Grow and rename a visited buffer and all its targets - (when (and (> (erc-networks--id-qualifying-len nid) - (erc-networks--id-qualifying-len other)) - (erc-networks--id-qualifying-grow-id other)) - ;; Rename NID's buffers using current ID - (erc-buffer-filter (lambda () - (when (eq erc-networks--id other) - (erc-networks--maybe-update-buffer-name))))))) - -(defun erc-networks--id-sort-buffers (buffers) - "Return a list of target BUFFERS, newest to oldest." - (sort buffers - (lambda (a b) - (> (erc-networks--id-ts (buffer-local-value 'erc-networks--id a)) - (erc-networks--id-ts (buffer-local-value 'erc-networks--id b)))))) - - -;;;; Buffer association - -(cl-defgeneric erc-networks--shrink-ids-and-buffer-names () - nil) ; concrete default implementation for non-eliding IDs - -(defun erc-networks--refresh-buffer-names (identity &optional omit) - "Ensure all colliding buffers for network IDENTITY have suffixes. -Then rename current buffer appropriately. Don't consider buffer OMIT -when determining collisions." - (if (erc-networks--examine-targets identity erc--target - #'ignore - (lambda () - (unless (or (not omit) (eq (current-buffer) omit)) - (erc-networks--ensure-unique-target-buffer-name) - t))) - (erc-networks--ensure-unique-target-buffer-name) - (rename-buffer (erc--target-string erc--target) 'unique))) - -;; This currently doesn't equalize related identities that may have -;; become mismatched because that shouldn't happen after a connection -;; is up (other than for a brief moment while renicking or similar, -;; when states are inconsistent). -(defun erc-networks--shrink-ids-and-buffer-names-any (&rest omit) - (let (grown) - ;; Gather all grown identities. - (erc-buffer-filter - (lambda () - (when (and erc-networks--id - (erc-networks--id-qualifying-p erc-networks--id) - (not (memq (current-buffer) omit)) - (not (memq erc-networks--id grown)) - (> (erc-networks--id-qualifying-len erc-networks--id) 1)) - (push erc-networks--id grown)))) - ;; Check for other identities with shared prefix. If none exists, - ;; and an identity is overlong, shrink it. - (dolist (nid grown) - (let ((skip (not (null omit)))) - (catch 'found - (if (cdr grown) - (dolist (other grown) - (unless (eq nid other) - (setq skip nil) - (when (erc-networks--id-qualifying-prefix-length nid other) - (throw 'found (setq skip t))))) - (setq skip nil))) - (unless (or skip (< (erc-networks--id-qualifying-len nid) 2)) - (erc-networks--id-qualifying-reset-id nid) - (erc-buffer-filter - (lambda () - (when (and (eq erc-networks--id nid) - (not (memq (current-buffer) omit))) - (if erc--target - (erc-networks--refresh-buffer-names nid omit) - (erc-networks--maybe-update-buffer-name)))))))))) - -(cl-defmethod erc-networks--shrink-ids-and-buffer-names - (&context (erc-networks--id erc-networks--id-qualifying)) - (erc-networks--shrink-ids-and-buffer-names-any (current-buffer))) - -(defun erc-networks-rename-surviving-target-buffer () - "Maybe drop qualifying suffix from fellow target-buffer's name. -But only do so when there's a single survivor with a target -matching that of the dying buffer." - (when-let* - (((with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers)) - (target erc--target) - ;; Buffer name includes ID suffix - ((not (string= (erc--target-symbol target) ; string= t "t" -> t - (erc-downcase (buffer-name))))) - (buf (current-buffer)) - ;; All buffers, not just those belonging to same process - (others (erc-buffer-filter - (lambda () - (and-let* ((erc--target) - ((not (eq buf (current-buffer)))) - ((eq (erc--target-symbol target) - (erc--target-symbol erc--target)))))))) - ((not (cdr others)))) - (with-current-buffer (car others) - (unless (get-buffer (erc--target-string target)) - (rename-buffer (erc--target-string target)))))) - -(defun erc-networks-shrink-ids-and-buffer-names () - "Recompute network IDs and buffer names, ignoring the current buffer. -Only do so when an IRC connection's context supports qualified -naming. Do not discriminate based on whether a buffer's -connection is active." - (erc-networks--shrink-ids-and-buffer-names)) - -(defun erc-networks--examine-targets (identity target on-dupe on-collision) - "Visit all ERC target buffers with the same TARGET. -Call ON-DUPE when a buffer's identity belongs to a network -IDENTITY or \"should\" after reconciliation. Call ON-COLLISION -otherwise. Neither function should accept any args. Expect -TARGET to be an `erc--target' object." - (declare (indent 2)) - (let ((announced erc-server-announced-name)) - (erc-buffer-filter - (lambda () - (when (and erc--target (eq (erc--target-symbol erc--target) - (erc--target-symbol target))) - ;; When a server sends administrative queries immediately - ;; after connection registration and before the session has a - ;; net-id, the buffer remains orphaned until reassociated - ;; here retroactively. - (unless erc-networks--id - (let ((id (erc-with-server-buffer erc-networks--id)) - (server-buffer (process-buffer erc-server-process))) - (apply #'erc-button--display-error-notice-with-keys - server-buffer - (concat "Missing network session (ID) for %S. " - (if id "Using `%S' from %S." "Ignoring.")) - (current-buffer) - (and id (list (erc-networks--id-symbol - (setq erc-networks--id id)) - server-buffer))))) - (when erc-networks--id - (let ((oursp (if (erc--target-channel-local-p target) - (equal announced erc-server-announced-name) - (erc-networks--id-equal-p identity - erc-networks--id)))) - (funcall (if oursp on-dupe on-collision))))))))) - -(defconst erc-networks--qualified-sep "@" - "Separator used for naming a target buffer.") - -(defun erc-networks--construct-target-buffer-name (target) - "Return TARGET@suffix." - (concat (erc--target-string target) - (if (with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers) - erc-networks--qualified-sep "/") - (cond - ((not (with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers)) - (cadr (split-string - (erc-networks--id-string erc-networks--id) - "/"))) - ((erc--target-channel-local-p target) erc-server-announced-name) - (t (erc-networks--id-string erc-networks--id))))) - -(defun erc-networks--ensure-unique-target-buffer-name () - (when-let* ((new-name (erc-networks--construct-target-buffer-name - erc--target)) - ((not (equal (buffer-name) new-name)))) - (rename-buffer new-name 'unique))) - -(defun erc-networks--ensure-unique-server-buffer-name () - (when-let* ((new-name (erc-networks--id-string erc-networks--id)) - ((not (equal (buffer-name) new-name)))) - (rename-buffer new-name 'unique))) - -(defun erc-networks--maybe-update-buffer-name () - "Update current buffer name to reflect display ID if necessary." - (if erc--target - (erc-networks--ensure-unique-target-buffer-name) - (erc-networks--ensure-unique-server-buffer-name))) - -(defun erc-networks--reconcile-buffer-names (target nid) - "Reserve preferred buffer name for TARGET and network identifier. -Expect TARGET to be an `erc--target' instance. Guarantee that at -most one existing buffer has the same `erc-networks--id' and a -case-mapped target, i.e., `erc--target-symbol'. If other buffers -with equivalent targets exist, rename them to TARGET@their-NID -and return TARGET@our-NID. Otherwise return TARGET as a string. -When multiple buffers for TARGET exist for the current NID, -rename them with suffixes going from newest to oldest." - (let* (existing ; Former selves or unexpected dupes (for now allow > 1) - ;; Renamed ERC buffers on other networks matching target - (namesakes (erc-networks--examine-targets nid target - (lambda () (push (current-buffer) existing) nil) - ;; Append network ID as TARGET@NID, - ;; possibly qualifying to achieve uniqueness. - (lambda () - (unless (erc--target-channel-local-p erc--target) - (erc-networks--id-ensure-comparable - nid erc-networks--id)) - (erc-networks--ensure-unique-target-buffer-name) - t))) - ;; Must follow ^ because NID may have been modified - (name (if (or namesakes (not (with-suppressed-warnings - ((obsolete erc-reuse-buffers)) - erc-reuse-buffers))) - (erc-networks--construct-target-buffer-name target) - (erc--target-string target))) - placeholder) - ;; If we don't exist, claim name temporarily while renaming others - (when-let* ((ex (get-buffer name)) - ((not (memq ex existing)))) - (if namesakes ; if namesakes is nonempty, it contains ex - (with-current-buffer ex - (let ((temp-name (generate-new-buffer-name (format "*%s*" name)))) - (rename-buffer temp-name) - (setq placeholder (get-buffer-create name)) - (rename-buffer name 'unique))) - ;; Here, ex must be a server buffer or a non-ERC buffer - (setq name (erc-networks--construct-target-buffer-name target)))) - (unless (with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers) - (when (string-suffix-p ">" name) - (setq name (string-trim-right name (rx "<" (+ digit) ">"))))) - (dolist (ex (erc-networks--id-sort-buffers existing)) - (with-current-buffer ex - (rename-buffer name 'unique))) - (when placeholder (kill-buffer placeholder)) - name)) - - -;; 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 - (declare (obsolete "maybe see `erc-networks--determine'" "29.1")) - (defvar erc-server-parameters) - (defvar erc-session-server) - (let ((network-name (cdr (assoc "NETWORK" erc-server-parameters)))) - (if network-name - (intern network-name) - (or - ;; Loop through `erc-networks-alist' looking for a match. - (let ((server (or erc-server-announced-name erc-session-server))) - (cl-loop for (name matcher) in erc-networks-alist - when (and matcher - (string-match (concat matcher "\\'") server)) - do (cl-return name))) - 'Unknown)))) - -(defun erc-network () - "Return the value of `erc-network' for the current server." - (or erc-network (erc-with-server-buffer erc-network))) - -(defun erc-network-name () - "Return the name of the current network as a string." - (erc-with-server-buffer (symbol-name erc-network))) - -(defun erc-set-network-name (_proc _parsed) - "Set `erc-network' to the value returned by `erc-determine-network'." - (declare (obsolete "maybe see `erc-networks--set-name'" "29.1")) - (unless erc-server-connected - (setq erc-network (with-suppressed-warnings - ((obsolete erc-determine-network)) - (erc-determine-network)))) - nil) - -(defconst erc-networks--name-missing-sentinel (gensym "Unknown ") - "Value to cover rare case of a literal NETWORK=nil.") - -(defun erc-networks--determine (&optional server) - "Return the name of the network as a symbol. -Search `erc-networks-alist' for a known entity matching SERVER or -`erc-server-announced-name'. If that fails, use the display name -given by the `RPL_ISUPPORT' NETWORK parameter." - (or (cl-loop for (name matcher) in erc-networks-alist - when (and matcher - (string-match (concat matcher "\\'") - (or server erc-server-announced-name))) - return name) - (and-let* ((vanity (erc--get-isupport-entry 'NETWORK 'single)) - ((intern vanity)))) - (erc-networks--id-given erc-networks--id) - erc-networks--name-missing-sentinel)) - -(defvar erc-networks--allow-unknown-network nil - "Whether to ignore a failure in identifying the network. -If you need this as a user option, please say so via \\[erc-bug]. -Otherwise, expect it to vanish at any time.") ; Bug#59976 - -(defun erc-networks--set-name (proc parsed) - "Set `erc-network' to the value returned by `erc-networks--determine'. -Print an error message when the network cannot be determined before -shutting down the connection." - ;; Always update (possibly clobber) current value, if any. - (pcase (setq erc-network (erc-networks--determine)) - ((and (pred (eq (erc-networks--id-given erc-networks--id))) - (let m (format "Couldn't determine network. Using given ID `%s'." - erc-network))) - (erc-display-message parsed 'notice nil m) - nil) - ((guard (eq erc-network erc-networks--name-missing-sentinel)) - ;; This can happen theoretically, e.g., when adjusting settings - ;; on a proxy service that partially impersonates IRC but isn't - ;; currently conveying anything through to a real network. The - ;; service may send a 422 but no NETWORK param (or *any* 005s). - (erc-button--display-error-notice-with-keys - "Failed to determine network. Please set entry for \"" - erc-server-announced-name "\" in `erc-networks-alist' or consider" - " calling `erc-tls' with the keyword `:id'." - " See Info:\"(erc) Network Identifier\" for more.") - (if erc-networks--allow-unknown-network - (progn - (erc-display-error-notice - parsed (format "Continuing anyway with network set to `%s'." - erc-network)) - nil) - (delete-process proc) - 'error)))) - -;; This lives here in this file because all the other "on connect" -;; MOTD stuff ended up here (but perhaps that needs to change). - -(defun erc-networks--ensure-announced (_ parsed) - "Set a fallback `erc-server-announced-name' if still unset. -Copy source (prefix) from MOTD-ish message as a last resort." - ;; The 004 handler never ran; see 2004-03-10 Diane Murray in change log - (unless erc-server-announced-name - (require 'erc-button) - (erc-button--display-error-notice-with-keys - "Failed to determine server name. Using \"" - (setq erc-server-announced-name (erc-response.sender parsed)) "\" instead" - ". If this was unexpected, consider reporting it via \\[erc-bug].")) - nil) - -(defun erc-unset-network-name (_nick _ip _reason) - "Set `erc-network' to nil." - (declare (obsolete "`erc-network' is now effectively read-only" "29.1")) - (setq erc-network nil) - nil) - -(defun erc-networks--transplant-buffer-content (src dest) - "Insert buffer SRC's contents into DEST, above its contents." - (with-silent-modifications - (let ((content (with-current-buffer src - (cl-assert (not (buffer-narrowed-p))) - (erc--insert-admin-message 'graft ?n dest ?o src) - (buffer-substring (point-min) erc-insert-marker)))) - (with-current-buffer dest - (save-excursion - (save-restriction - (cl-assert (not (buffer-narrowed-p))) - (goto-char (point-min)) - (while (and (eql ?\n (char-after (point))) - (null (text-properties-at (point)))) - (delete-char 1)) - (insert-before-markers content))))))) - -(defvar erc-networks--transplant-target-buffer-function - #'erc-networks--transplant-buffer-content - "Function to rename and merge the contents of two target buffers. -Called with the donating buffer to be killed and buffer to receive the -transplant. Consuming modules can leave a marker at the beginning of -the latter buffer to access the insertion point, if needing to do things -like adjust invisibility properties, etc.") - -(defvar erc-networks--target-transplant-in-progress-p nil - "Non-nil when merging target buffers.") - -;; This should run whenever a network identity is updated. -(defun erc-networks--reclaim-orphaned-target-buffers (new-proc nid announced) - "Visit disowned buffers for same NID and associate with NEW-PROC. -Expect ANNOUNCED to be the server's reported host name." - (erc-buffer-filter - (lambda () - (when (and erc--target - (not erc-server-connected) - (erc-networks--id-equal-p erc-networks--id nid) - (or (not (erc--target-channel-local-p erc--target)) - (string= erc-server-announced-name announced))) - ;; If a target buffer exists for the current process, kill this - ;; stale one after transplanting its content; else reinstate. - (if-let ((actual (erc-get-buffer (erc--target-string erc--target) - new-proc)) - (erc-networks--target-transplant-in-progress-p t)) - (progn - (funcall erc-networks--transplant-target-buffer-function - (current-buffer) actual) - (kill-buffer (current-buffer)) - (with-current-buffer actual - (erc-networks--ensure-unique-target-buffer-name))) - (setq erc-server-process new-proc - erc-server-connected t - erc-networks--id nid)))))) - -;; For existing buffers, `erc-open' reinitializes a core set of local -;; variables in addition to some text, such as the prompt. It expects -;; module activation functions to do the same for assets they manage. -;; However, "stateful" modules, whose functionality depends on the -;; evolution of a buffer's content, may need to reconcile state during -;; a merge. An example might be a module that provides consistent -;; timestamps: it should ensure time values don't decrease. -(defvar erc-networks--copy-server-buffer-functions nil - "Abnormal hook run in new server buffers when deduping. -Passed the existing buffer to be killed, whose contents have -already been copied over to the current, replacement buffer.") - -(defun erc-networks--copy-over-server-buffer-contents (existing name) - "Kill off existing server buffer after copying its contents. -Expect to be called from the replacement buffer." - (defvar erc-kill-buffer-hook) - (defvar erc-kill-server-hook) - ;; The following observations from ERC 5.5 regarding the buffer - ;; `existing' were thought at the time to be invariants: - ;; - `erc-networks--id' is `erc-networks--id-equal-p' to the - ;; caller's network identity and older if not `eq'. - ;; - `erc-server-process' should be set (local) but dead and `eq' to - ;; the result of `get-buffer-process' unless the latter is nil. - (delete-process (buffer-local-value 'erc-server-process existing)) - (erc-networks--transplant-buffer-content existing (current-buffer)) - (let (erc-kill-server-hook erc-kill-buffer-hook) - (run-hook-with-args 'erc-networks--copy-server-buffer-functions existing) - (kill-buffer name))) - -;; This stands alone for testing purposes - -(defun erc-networks--update-server-identity () - "Maybe grow or replace the current network identity. -If a dupe is found, adopt its identity by overwriting ours. -Otherwise, take steps to ensure it can effectively be compared to -ours, now and into the future. Note that target buffers are -considered as well because server buffers are often killed." - (let* ((identity erc-networks--id) - (buffer (current-buffer)) - (f (lambda () - (unless (or (not erc-networks--id) - (eq (current-buffer) buffer) - (eq erc-networks--id identity)) - (if (erc-networks--id-equal-p identity erc-networks--id) - (throw 'buffer erc-networks--id) - (erc-networks--id-ensure-comparable identity - erc-networks--id) - nil)))) - (found (catch 'buffer (erc-buffer-filter f)))) - (when found - (setq erc-networks--id found)))) - -;; These steps should only run when initializing a newly connected -;; server buffer, whereas `erc-networks--rename-server-buffer' can run -;; mid-session, after an identity's core components have changed. - -(defun erc-networks--init-identity (proc parsed) - "Update identity with real network name." - ;; Initialize identity for real now that we know the network - (cl-assert erc-network) - (if erc-networks--id - (erc-networks--id-reload erc-networks--id proc parsed) - (setq erc-networks--id (erc-networks--id-create nil)) - ;; Find duplicate identities or other conflicting ones and act - ;; accordingly. - (erc-networks--update-server-identity) - (erc-networks--rename-server-buffer proc parsed)) - nil) - -(defun erc-networks--rename-server-buffer (new-proc &optional _parsed) - "Rename a server buffer based on its network identity. -Assume that the current buffer is a server buffer, either one -with a newly established connection whose identity has just been -fully fleshed out, or an existing one whose identity has just -been updated. Either way, assume the current identity is ready -to serve as a canonical identifier. - -When a server buffer already exists with the chosen name, copy -over its contents and kill it. However, when its process is -still alive, kill off the current buffer. This can happen, for -example, after a perceived loss in network connectivity turns out -to be a false alarm. If `erc-reuse-buffers' is nil, let -`generate-new-buffer-name' do the actual renaming." - (cl-assert (eq new-proc erc-server-process)) - (cl-assert (erc-networks--id-symbol erc-networks--id)) - ;; Always look for targets to reassociate because original server - ;; buffer may have been deleted. - (erc-networks--reclaim-orphaned-target-buffers new-proc erc-networks--id - erc-server-announced-name) - (let* ((name (erc-networks--id-string erc-networks--id)) - ;; When this ends up being the current buffer, either we have - ;; a "given" ID or the buffer was reused on reconnecting. - (existing (get-buffer name))) - (process-put new-proc 'erc-networks--id erc-networks--id) - (cond ((or (not existing) - (erc-networks--id-given erc-networks--id) - (eq existing (current-buffer))) - (rename-buffer name)) - ;; Abort on accidental reconnect or failure to pass :id param for - ;; avoidable collisions. - ((erc-server-process-alive existing) - (kill-local-variable 'erc-network) - (delete-process new-proc) - (erc-display-error-notice nil (format "Buffer %s still connected" - name)) - (erc-set-active-buffer existing)) - ;; Copy over old buffer's contents and kill it - ((with-suppressed-warnings ((obsolete erc-reuse-buffers)) - erc-reuse-buffers) - (erc-networks--copy-over-server-buffer-contents existing name) - (rename-buffer name)) - (t (rename-buffer (generate-new-buffer-name name))))) - nil) - -;; Soju v0.4.0 sends ISUPPORT and nothing else on upstream reconnect, -;; so this actually doesn't apply. ZNC 1.8.2, however, still sends -;; the entire burst. -(defvar erc-networks--bouncer-targets '(*status bouncerserv) - "Symbols matching proxy-bot targets.") - -(defun erc-networks-on-MOTD-end (proc parsed) - "Call on-connect functions with server PROC and PARSED message." - ;; This should normally run before `erc-server-connected' is set. - ;; However, bouncers and other proxies may interfere with that. - (when erc-server-connected - (unless (erc-buffer-filter (lambda () - (and erc--target - (memq (erc--target-symbol erc--target) - erc-networks--bouncer-targets))) - proc) - (require 'erc-button) - (erc-button--display-error-notice-with-keys - "Unexpected state detected. Please report via \\[erc-bug]."))) - - ;; For now, retain compatibility with erc-server-NNN-functions. - (or (erc-networks--ensure-announced proc parsed) - (erc-networks--set-name proc parsed) - (erc-networks--init-identity proc parsed))) - -(define-erc-module networks nil - "Provide data about IRC networks." - ((add-hook 'erc-server-376-functions #'erc-networks-on-MOTD-end) - (add-hook 'erc-server-422-functions #'erc-networks-on-MOTD-end)) - ((remove-hook 'erc-server-376-functions #'erc-networks-on-MOTD-end) - (remove-hook 'erc-server-422-functions #'erc-networks-on-MOTD-end))) - -(defun erc-networks--warn-on-connect () - "Emit warning when the `networks' module hasn't been loaded. -Ideally, do so upon opening the network process." - (unless (or erc--target erc-networks-mode) - (let ((m (concat "Required module `networks' not loaded. If this " - " was unexpected, please add it to `erc-modules'."))) - ;; Assume the server buffer has been marked as active. - (erc-display-error-notice - nil (concat m " See Info:\"(erc) Required Modules\" for more.")) - (lwarn 'erc :warning m)))) - -(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 (ensure-list ports)) - (cond ((numberp p) - (push p result)) - ((listp p) - (setq result (nconc (cl-loop for i from (cadr p) downto (car p) - collect i) - result))))) - (nreverse result))) - -(defun erc-networks--server-select () - "Prompt for a server in `erc-server-alist' and return its irc(s):// URL. -Choose port at random if multiple candidates exist, but always -prefer TLS without asking. When a port can't be determined, -return the host alone sans URL formatting (for compatibility)." - (let* ((net (intern - (completing-read-case-insensitive - "Network: " - (delete-dups - (mapcar (lambda (x) - (list (nth 1 x))) - erc-server-alist))))) - (s-choose (lambda (entry) - (and (equal (nth 1 entry) net) - (if-let ((b (string-search ": " (car entry)))) - (cons (format "%s (%s)" (nth 2 entry) - (substring (car entry) (+ b 2))) - (cdr entry)) - entry)))) - (s-entries (delq nil (mapcar s-choose erc-server-alist))) - (srv (assoc (completing-read-case-insensitive "Server: " s-entries) - s-entries)) - (host (nth 2 srv)) - (pspec (nthcdr 3 srv)) - (ports (erc-ports-list (or (cadr pspec) (car pspec)))) - (scheme (if (cdr pspec) "ircs" "irc"))) - (if ports (format "%s://%s:%d" scheme host (seq-random-elt ports)) host))) - -;;; The following experimental -;; It does not work yet, help me with it if you -;; think it is worth the effort. - -(defvar erc-settings - '((pals Libera.Chat ("kensanata" "shapr" "anti\\(fuchs\\|gone\\)")) - (format-nick-function (Libera.Chat "#emacs") erc-format-@nick)) - "Experimental: Alist of configuration options. - -WARNING: this variable is a vestige from a long-abandoned -experiment. ERC may redefine it using the same name for any -purpose at any time. - -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.") -(make-obsolete-variable 'erc-settings - "temporarily deprecated for later repurposing" "30.1") - -(defun erc-get (var &optional net target) - "Retrieve configuration values from `erc-settings'. - -WARNING: this function is a non-functioning remnant from a -long-abandoned experiment. ERC may redefine it using the same -name for any purpose at any time. - -\(fn &rest UNKNOWN)" - (declare (obsolete "temporarily deprecated for later repurposing" "30.1")) - (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 'Libera.Chat) - -(provide 'erc-networks) - -;;; erc-networks.el ends here diff --git a/lisp/erc/erc-nicks.el b/lisp/erc/erc-nicks.el deleted file mode 100644 index a25d39610af..00000000000 --- a/lisp/erc/erc-nicks.el +++ /dev/null @@ -1,809 +0,0 @@ -;;; erc-nicks.el -- Nick colors for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2023-2025 Free Software Foundation, Inc. - -;; Author: David Leatherman -;; Andy Stewart - -;; 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 3 of the License, -;; 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. If not, see . - -;;; Commentary: - -;; This file provides the `nicks' module for automatic nickname -;; highlighting. Add `nicks' to `erc-modules' to get started. -;; -;; Use the command `erc-nicks-refresh' to review changes after -;; adjusting an option, like `erc-nicks-contrast-range'. To change -;; the color of a nickname in a target buffer, click on it and choose -;; "Edit face" from the completion interface, and then perform your -;; adjustments in the resulting Customize menu. Non-Customize users -;; on Emacs 28+ can persist changes permanently by clicking on the -;; face's "location" hyperlink and copying the generated code snippet -;; (`defface' or `use-package') to their init.el. Customize users -;; need only click "Apply and Save", as usual. - -;;; History: - -;; This module has enjoyed a number of contributors across several -;; variants over the years, including: -;; -;; Thibault Polge -;; Jay Kamat -;; Alex Kost -;; Antoine Levitt -;; Adam Porter -;; -;; To those not mentioned, your efforts are no less appreciated. - -;; 2023/05 - erc-nicks -;; Rewrite using internal API, and rebrand for ERC 5.6 -;; 2020/03 - erc-hl-nicks 1.3.4 -;; Final release, see [1] for intervening history -;; 2014/05 - erc-highlight-nicknames.el -;; Final release, see [2] for intervening history -;; 2011/08 - erc-hl-nicks 1.0 -;; Initial release forked from erc-highlight-nicknames.el -;; 2008/12 - erc-highlight-nicknames.el -;; First release from Andy Stewart -;; 2007/09 - erc-highlight-nicknames.el -;; Initial release by André Riemann - -;; [1] -;; [2] - -;;; Code: - -(require 'erc-button) -(require 'color) - -(defgroup erc-nicks nil - "Colorize nicknames in ERC target buffers." - :package-version '(ERC . "5.6") - :group 'erc) - -(defcustom erc-nicks-ignore-chars ",`'_-" - "Trailing characters in a nick to ignore while highlighting. -Value should be a string containing characters typically appended -by IRC clients to secure a nickname after a rejection (see option -`erc-nick-uniquifier'). A value of nil means don't trim -anything." - :type '(choice (string :tag "Chars to trim") - (const :tag "Don't trim" nil))) - -(defcustom erc-nicks-skip-nicks nil - "Nicks to avoid highlighting. -ERC only considers this option during module activation, so users -should adjust it before connecting." - :type '(repeat string)) - -(defcustom erc-nicks-skip-faces '(erc-notice-face erc-my-nick-face) - "Faces to avoid highlighting atop." - :type '(repeat face) - :package-version '(ERC . "5.6.1")) - -(defcustom erc-nicks-backing-face erc-button-nickname-face - "Face to mix with generated one for emphasizing non-speakers." - :type '(choice face (const nil))) - -(defcustom erc-nicks-bg-color - (frame-parameter (selected-frame) 'background-color) - "Background color for calculating contrast. -Set this explicitly when the background color isn't discoverable, -which may be the case in terminal Emacs. Even when automatically -initialized, this value may need adjustment mid-session, such as -after loading a new theme. Remember to run \\[erc-nicks-refresh] -after doing so." - :type 'string) - -(defcustom erc-nicks-color-adjustments - '(erc-nicks-add-contrast erc-nicks-cap-contrast erc-nicks-ensaturate) - "Treatments applied to improve aesthetics or visibility. -For example, the function `erc-nicks-invert' inverts a nick when -it's too close to the background, and `erc-nicks-add-contrast' -attempts to find a decent contrast ratio by brightening or -darkening. When `erc-nicks-colors' is set to the symbol -`defined' or a user-provided list of colors, ERC uses this option -as a guide for culling any colors that don't fall within -`erc-nicks-contrast-range' or `erc-nicks-saturation-range', as -appropriate. For example, if `erc-nicks-cap-contrast' is present -in this option's value, and a color's contrast exceeds the CDR of -`erc-nicks-contrast-range', ERC will purge that color from its -rolls when initializing this module. Specify a value of nil to -inhibit this process." - :type '(repeat - (choice (function-item :tag "Invert" erc-nicks-invert) - (function-item :tag "Add contrast" erc-nicks-add-contrast) - (function-item :tag "Cap contrast" erc-nicks-cap-contrast) - (function-item :tag "Bound saturation" erc-nicks-ensaturate) - function))) - -(defcustom erc-nicks-contrast-range '(4.3 . 12.5) - "Desired range of contrast as a cons of (MIN . MAX). -When `erc-nicks-add-contrast' and/or `erc-nicks-invert' appear in -`erc-nicks-color-adjustments', MIN specifies the minimum amount -of contrast allowed between a buffer's background and its -foreground colors. Depending on the background, nicks may appear -tinted in pastels or shaded with muted grays. MAX works -similarly for reducing contrast, but only when -`erc-nicks-cap-contrast' is active. Users with lighter -backgrounds may want to lower MAX significantly. Either value -can range from 1.0 to 21.0(:1) but may produce unsatisfactory -results toward either extreme." - :type '(cons float float)) - -(defcustom erc-nicks-saturation-range '(0.2 . 0.8) - "Desired range for constraining saturation. -Expressed as a cons of decimal proportions. Only matters when -`erc-nicks-ensaturate' appears in `erc-nicks-color-adjustments'." - :type '(cons float float)) - -(defcustom erc-nicks-colors 'all - "Pool of colors. -List of colors as strings (hex or named) or, alternatively, a -single symbol representing a set of colors, like that produced by -the function `defined-colors', which ERC associates with the -symbol `defined'. Similarly, `all' tells ERC to use any 24-bit -color. After updating this option's value mid-session, try -\\[erc-nicks-refresh]." - :type `(choice (const :tag "All 24-bit colors" all) - (const :tag "Defined terminal colors" defined) - (const :tag "Font Lock faces" font-lock) - (const :tag "ANSI color faces" ansi-color) - (repeat :tag "User-provided list" string))) - -(defcustom erc-nicks-key-suffix-format "@%n" - "Template for latter portion of keys to generate colors from. -ERC passes this to `format-spec' with the following specifiers: -%n for the current network and %m for your nickname (not the one -being colorized). If you don't like the generated palette, try -adding extra characters or padding, for example, with something -like \"@%-012n\"." - :type 'string) - -(defcustom erc-nicks-track-faces 'prioritize - "Show nick faces in the `track' module's portion of the mode line. -A value of nil means don't show `nicks'-managed faces at all. A value -of t means treat them as non-\"normal\" faces ranked at or below -`erc-default-face'. This has the effect of always showing them while -suppressing the \"alternating\" behavior normally associated with -`erc-track-faces-normal-list' (including between the speaker and nicks -mentioned in the message body.) A value of `defer' means treat nicks as -unranked normals to favor alternating between them and ranked normals. -A value of `prioritize' exhibits the same alternating effect as `defer' -when speakers stay the same but allows a new speaker's face to -impersonate a ranked normal so that adjacent speakers alternate among -themselves before deferring to non-face normals. Like most options in -this module, updating the value mid-session is not officially supported, -although cycling \\[erc-nicks-mode] may be worth a shot." - :type '(choice boolean (const defer) (const prioritize))) - -(defvar erc-nicks--max-skip-search 3 ; make this an option? - "Max number of faces to visit when testing `erc-nicks-skip-faces'.") - -(defvar erc-nicks--colors-rejects nil) -(defvar erc-nicks--custom-keywords '(:group erc-nicks :group erc-faces)) -(defvar erc-nicks--grad-steps 9) - -(defvar-local erc-nicks--face-table nil - "Hash table mapping nicks to unique, named faces. -Keys are nonempty strings but need not be valid nicks.") - -(defvar-local erc-nicks--downcased-skip-nicks nil - "Case-mapped copy of `erc-nicks-skip-nicks'.") - -(defvar-local erc-nicks--bg-luminance nil) -(defvar-local erc-nicks--bg-mode-value nil) -(defvar-local erc-nicks--colors-len nil) -(defvar-local erc-nicks--colors-pool nil) -(defvar-local erc-nicks--fg-rgb nil) - -(defvar help-xref-stack) -(defvar help-xref-stack-item) -(defvar erc-track--normal-faces) - -;; https://stackoverflow.com/questions/596216#answer-56678483 -(defun erc-nicks--get-luminance (color) - "Return relative luminance of COLOR. -COLOR can be a list of normalized values or a name. This is the -same as the Y component returned by `color-srgb-to-xyz'." - (let ((out 0) - (coefficients '(0.2126 0.7152 0.0722)) - (chnls (if (stringp color) (color-name-to-rgb color) color))) - (dolist (ch chnls out) - (cl-incf out (* (pop coefficients) - (if (<= ch 0.04045) - (/ ch 12.92) - (expt (/ (+ ch 0.055) 1.055) 2.4))))))) - -(defun erc-nicks--get-contrast (fg &optional bg) - "Return a float between 1 and 21 for colors FG and BG. -If FG or BG are floats, interpret them as luminance values." - (let* ((lum-fg (if (numberp fg) fg (erc-nicks--get-luminance fg))) - (lum-bg (if bg - (if (numberp bg) bg (erc-nicks--get-luminance bg)) - (or erc-nicks--bg-luminance - (setq erc-nicks--bg-luminance - (erc-nicks--get-luminance erc-nicks-bg-color)))))) - (when (< lum-fg lum-bg) (cl-rotatef lum-fg lum-bg)) - (/ (+ 0.05 lum-fg) (+ 0.05 lum-bg)))) - -(defmacro erc-nicks--bg-mode () - `(or erc-nicks--bg-mode-value - (setq erc-nicks--bg-mode-value - ,(cond ((fboundp 'frame--current-background-mode) - '(frame--current-background-mode (selected-frame))) - ((fboundp 'frame--current-backround-mode) - '(frame--current-backround-mode (selected-frame))) - (t - '(frame-parameter (selected-frame) 'background-mode)))))) - -;; https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html -(defun erc-nicks--adjust-contrast (color target &optional decrease) - (cl-assert erc-nicks--fg-rgb) - (let* ((lum-bg (or erc-nicks--bg-luminance - (setq erc-nicks--bg-luminance - (erc-nicks--get-luminance erc-nicks-bg-color)))) - (stop (if decrease - (color-name-to-rgb erc-nicks-bg-color) - erc-nicks--fg-rgb)) - ;; From `color-gradient' in color.el - (r (nth 0 color)) - (g (nth 1 color)) - (b (nth 2 color)) - (interval (float (1+ (expt 2 erc-nicks--grad-steps)))) - (r-step (/ (- (nth 0 stop) r) interval)) - (g-step (/ (- (nth 1 stop) g) interval)) - (b-step (/ (- (nth 2 stop) b) interval)) - (maxtries erc-nicks--grad-steps) - started) - ;; FIXME stop when sufficiently close instead of exhausting. - (while (let* ((lum-fg (erc-nicks--get-luminance (list r g b))) - (darker (if (< lum-bg lum-fg) lum-bg lum-fg)) - (lighter (if (= darker lum-bg) lum-fg lum-bg)) - (cur (/ (+ 0.05 lighter) (+ 0.05 darker))) - (scale (expt 2 maxtries))) - (cond ((if decrease (> cur target) (< cur target)) - (setq r (+ r (* r-step scale)) - g (+ g (* g-step scale)) - b (+ b (* b-step scale)))) - (started - (setq r (- r (* r-step scale)) - g (- g (* g-step scale)) - b (- b (* b-step scale)))) - (t (setq maxtries 1))) - (unless started - (setq started t)) - (setq r (min 1.0 (max 0 r)) - g (min 1.0 (max 0 g)) - b (min 1.0 (max 0 b))) - (not (zerop (cl-decf maxtries))))) - (list r g b))) - -(defun erc-nicks-add-contrast (color) - "Increase COLOR's contrast by blending it with the foreground. -Unless sufficient contrast exists between COLOR and the -background, raise it to meet the lower bound of -`erc-nicks-contrast-range'." - (erc-nicks--adjust-contrast color (car erc-nicks-contrast-range))) - -(defun erc-nicks-cap-contrast (color) - "Reduce COLOR's contrast by blending it with the background. -If excessive contrast exists between COLOR and the background, -lower it to the upper bound of `erc-nicks-contrast-range'." - (erc-nicks--adjust-contrast color (cdr erc-nicks-contrast-range) 'remove)) - -(defun erc-nicks-invert (color) - "Invert COLOR based on the CAR of `erc-nicks-contrast-range'. -Don't bother if the inverted color has less contrast than the -input." - (if-let ((con-input (erc-nicks--get-contrast color)) - ((< con-input (car erc-nicks-contrast-range))) - (flipped (mapcar (lambda (c) (- 1.0 c)) color)) - ((> (erc-nicks--get-contrast flipped) con-input))) - flipped - color)) - -(defun erc-nicks-ensaturate (color) - "Ensure COLOR falls within `erc-nicks-saturation-range'." - (pcase-let ((`(,min . ,max) erc-nicks-saturation-range) - (`(,h ,s ,l) (apply #'color-rgb-to-hsl color))) - (cond ((> s max) (setq color (color-hsl-to-rgb h max l))) - ((< s min) (setq color (color-hsl-to-rgb h min l))))) - color) - -;; From https://elpa.gnu.org/packages/ement. The bit depth has been -;; scaled up to try and avoid components being exactly 0.0, which our -;; contrast function doesn't seem to like. -(defun erc-nicks--gen-color (string) - "Generate normalized RGB color from STRING." - (let* ((ratio (/ (float (abs (random string))) (float most-positive-fixnum))) - (color-num (round (* #xffffffffffff ratio)))) - (list (/ (float (logand color-num #xffff)) #xffff) - (/ (float (ash (logand color-num #xffff0000) -16)) #xffff) - (/ (float (ash (logand color-num #xffff00000000) -32)) #xffff)))) - -;; This doesn't add an entry to the face table because "@" faces are -;; interned in the global `obarray' and thus easily accessible. -(defun erc-nicks--revive (new-face old-face nick net) - (put new-face 'erc-nicks--custom-face t) - (put new-face 'erc-nicks--nick nick) - (put new-face 'erc-nicks--netid erc-networks--id) - (put old-face 'erc-nicks--key nil) - (apply #'custom-declare-face new-face (face-user-default-spec old-face) - (format "Persistent `erc-nicks' color for %s on %s." nick net) - erc-nicks--custom-keywords)) - -(defun erc-nicks--create-defface-template (face) - (pop-to-buffer (get-buffer-create (format "*New face %s*" face))) - (erase-buffer) - (lisp-interaction-mode) - (insert ";; If you *don't* use Customize, put something like this in your\n" - (substitute-command-keys - ";; init.el and use \\[eval-last-sexp] to apply any edits.\n\n") - (format "(defface %s\n '%S\n %S" - face (face-user-default-spec face) (face-documentation face)) - (cl-loop for (k v) on erc-nicks--custom-keywords by #'cddr - concat (format "\n %s %S" k (list 'quote v))) - ")\n\n;; Or, if you use use-package\n(use-package erc-nicks\n" - " :custom-face\n" - (format " (%s %S)" face (face-user-default-spec face)) - ")\n")) - -(defun erc-nicks--redirect-face-widget-link (args) - (pcase args - (`(,widget face-link . ,plist) - (when-let ((face (widget-value widget)) - ((get face 'erc-nicks--custom-face))) - (unless (symbol-file face) - (setf (plist-get plist :action) - (lambda (&rest _) (erc-nicks--create-defface-template face)))) - (setf (plist-get plist :help-echo) "Create or edit `defface'." - (cddr args) plist)))) - args) - -(defun erc-nicks--reduce (color) - "Fold adjustment strategies over COLOR, a string or normalized triple. -Return a hex string." - (apply #'color-rgb-to-hex - (seq-reduce (lambda (color strategy) (funcall strategy color)) - erc-nicks-color-adjustments - (if (stringp color) (color-name-to-rgb color) color)))) - -(defvar erc-nicks--create-pool-function (if (display-graphic-p) - #'erc-nicks--create-culled-pool - #'erc-nicks--create-coerced-pool) - "Filter function for initializing the pool of colors. -Takes a list of adjustment functions, such as those named in -`erc-nicks-color-adjustments', and a list of colors. Returns another -list whose members need not be among the original candidates.") - -(defun erc-nicks--create-coerced-pool (adjustments colors) - "Return COLORS that fall within parameters heeded by ADJUSTMENTS. -Apply ADJUSTMENTS and dedupe after replacing adjusted values with -those nearest defined for the terminal. Only perform one pass. -That is, accept the nearest initially found as \"close enough,\" -knowing that values may fall outside desired parameters and thus -yield a larger pool than simple culling might produce. When -debugging, add candidates to `erc-nicks--colors-rejects' that map -to the same output color as some prior candidate. Only effective -on non-graphical displays." - (let* ((seen (make-hash-table :test #'equal)) - (erc-nicks-color-adjustments adjustments) - pool) - (dolist (color colors) - (let ((quantized (car (tty-color-approximate - (color-values (erc-nicks--reduce color)))))) - (if (gethash quantized seen) - (when erc-nicks--colors-rejects - (push color erc-nicks--colors-rejects)) - (push quantized pool) - (puthash quantized color seen)))) - (nreverse pool))) - -(defun erc-nicks--create-culled-pool (adjustments colors) - "Return COLORS that fall within parameters indicated by ADJUSTMENTS." - (let (addp capp satp pool) - (dolist (adjustment adjustments) - (pcase adjustment - ((or 'erc-nicks-invert 'erc-nicks-add-contrast) (setq addp t)) - ('erc-nicks-cap-contrast (setq capp t)) - ('erc-nicks-ensaturate (setq satp t)))) - (dolist (color colors) - (let* ((rgb (color-name-to-rgb color)) - (contrast (and (or addp capp) (erc-nicks--get-contrast rgb)))) - (if (or (and addp (< contrast (car erc-nicks-contrast-range))) - (and capp (> contrast (cdr erc-nicks-contrast-range))) - (and-let* ((satp) - (s (cadr (apply #'color-rgb-to-hsl rgb)))) - (or (< s (car erc-nicks-saturation-range)) - (> s (cdr erc-nicks-saturation-range))))) - (when erc-nicks--colors-rejects - (push color erc-nicks--colors-rejects)) - (push color pool)))) - (nreverse pool))) - -(defun erc-nicks--init-pool () - "Initialize colors and optionally display faces or color palette." - (unless (eq erc-nicks-colors 'all) - (let* ((colors (or (and (listp erc-nicks-colors) erc-nicks-colors) - (and (memq erc-nicks-colors '(font-lock ansi-color)) - (erc-nicks--colors-from-faces - (format "%s-" erc-nicks-colors))) - (defined-colors))) - (pool (funcall erc-nicks--create-pool-function - erc-nicks-color-adjustments colors))) - (setq erc-nicks--colors-pool pool - erc-nicks--colors-len (length pool))))) - -(defun erc-nicks--determine-color (key) - (if (eq erc-nicks-colors 'all) - (erc-nicks--reduce (erc-nicks--gen-color key)) - (let ((pool (erc-with-server-buffer erc-nicks--colors-pool)) - (len (erc-with-server-buffer erc-nicks--colors-len))) - (nth (% (abs (random key)) len) pool)))) - -(defun erc-nicks--get-face (nick key) - "Retrieve a face for trimmed and downcased NICK. -If NICK is new, use KEY to derive color, and store under NICK. -Favor a custom erc-nicks-NICK@NETWORK-face when defined." - (let ((table (erc-with-server-buffer erc-nicks--face-table))) - (or (gethash nick table) - (and-let* ((face (intern-soft (concat "erc-nicks-" nick "@" - (erc-network-name) "-face"))) - ((or (and (facep face) face) - (erc-nicks--revive face face nick (erc-network)))))) - (let ((color (erc-nicks--determine-color key)) - (new-face (make-symbol (concat "erc-nicks-" nick "-face")))) - (put new-face 'erc-nicks--nick nick) - (put new-face 'erc-nicks--netid erc-networks--id) - (put new-face 'erc-nicks--key key) - (face-spec-set new-face `((t :foreground ,color - :inherit ,erc-nicks-backing-face)) - 'face-defface-spec) - (set-face-documentation - new-face (format "Internal face for %s on %s." nick (erc-network))) - (puthash nick new-face table))))) - -(define-inline erc-nicks--anon-face-p (face) - (inline-quote (and (consp ,face) (pcase (car ,face) - ((pred keywordp) t) - ('foreground-color t) - ('background-color t))))) - -(defun erc-nicks--skip-p (prop option limit) - "Return non-nil if a face in PROP appears in OPTION. -Abandon search after examining LIMIT faces." - (setq prop (if (erc-nicks--anon-face-p prop) (list prop) (ensure-list prop))) - (catch 'found - (while-let (((> limit 0)) - (elem (pop prop))) - (while (and (consp elem) (not (erc-nicks--anon-face-p elem))) - (when (cdr elem) - (push (cdr elem) prop)) - (setq elem (car elem))) - (when elem - (cl-decf limit) - (when (if (symbolp elem) (memq elem option) (member elem option)) - (throw 'found elem)))))) - -(defun erc-nicks--trim (nickname) - "Return downcased NICKNAME sans trailing `erc-nicks-ignore-chars'." - (erc-downcase - (if erc-nicks-ignore-chars - (string-trim-right nickname - (rx-to-string - `(: (+ (any ,erc-nicks-ignore-chars)) eot))) - nickname))) - -(defun erc-nicks--gen-key-from-format-spec (nickname) - "Generate key for NICKNAME according to `erc-nicks-key-suffix-format'." - (concat nickname (format-spec erc-nicks-key-suffix-format - `((?n . ,(erc-network)) - (?m . ,(erc-current-nick)))))) - -(defun erc-nicks--highlight (nickname &optional base-face) - "Return face for NICKNAME unless it or BASE-FACE is blacklisted." - (when-let ((trimmed (erc-nicks--trim nickname)) - ((not (member trimmed erc-nicks--downcased-skip-nicks))) - ((not (and base-face - (erc-nicks--skip-p base-face erc-nicks-skip-faces - erc-nicks--max-skip-search)))) - (key (erc-nicks--gen-key-from-format-spec trimmed))) - (erc-nicks--get-face trimmed key))) - -(defun erc-nicks--highlight-button (nick-object) - "Possibly add face to `erc-button--nick-user' NICK-OBJECT." - (when-let - ((nick-object) - (face (get-text-property (car (erc-button--nick-bounds nick-object)) - 'font-lock-face)) - (nick (erc-server-user-nickname (erc-button--nick-user nick-object))) - (out (erc-nicks--highlight nick face))) - (setf (erc-button--nick-nickname-face nick-object) out - ;; - (erc-button--nick-face-cache nick-object) - (and erc-nicks-track-faces - (bound-and-true-p erc-track--normal-faces) - #'erc-nicks--remember-face-for-track))) - nick-object) - -(define-erc-module nicks nil - "Uniquely colorize nicknames in target buffers. - -This module is local per connection." - ((if erc--target - (progn - (erc-with-server-buffer - (unless erc-nicks-mode - (erc--warn-once-before-connect 'erc-nicks-mode - "Module `nicks' must be enabled or disabled session-wide." - " Toggling it in individual target buffers is unsupported.") - (erc-nicks-mode +1))) ; but do it anyway - (setq erc-nicks--downcased-skip-nicks - (mapcar #'erc-downcase erc-nicks-skip-nicks) - erc-nicks--fg-rgb (erc-with-server-buffer erc-nicks--fg-rgb)) - (add-function :filter-return (local 'erc-button--modify-nick-function) - #'erc-nicks--highlight-button '((depth . 80))) - (erc-button--phantom-users-mode +1)) - (unless erc-button-mode - (unless (memq 'button erc-modules) - (erc--warn-once-before-connect 'erc-nicks-mode - "Enabling default global module `button' needed by local" - " module `nicks'. This will impact \C-]all\C-] ERC" - " sessions. Add `button' to `erc-modules' to avoid this" - " warning. See Info:\"(erc) Modules\" for more.")) - (erc-button-mode +1)) - (when (equal erc-nicks-bg-color "unspecified-bg") - (let ((temp (if (eq (erc-nicks--bg-mode) 'light) "white" "black"))) - (erc-button--display-error-notice-with-keys - "Module `nicks' unable to determine background color. Setting to \"" - temp "\" globally. Please see `erc-nicks-bg-color'.") - (custom-set-variables (list 'erc-nicks-bg-color temp)))) - (setq erc-nicks--fg-rgb - (or (color-name-to-rgb - (face-foreground 'erc-default-face nil 'default)) - (color-name-to-rgb - (readable-foreground-color erc-nicks-bg-color)))) - (erc-nicks--init-pool) - (erc--restore-initialize-priors erc-nicks-mode - erc-nicks--face-table (make-hash-table :test #'equal))) - (setf (alist-get "Edit face" erc-button--nick-popup-alist nil nil #'equal) - #'erc-nicks-customize-face) - (erc-nicks--setup-track-integration) - (add-hook 'erc-track-mode-hook #'erc-nicks--setup-track-integration 50 t) - (advice-add 'widget-create-child-and-convert :filter-args - #'erc-nicks--redirect-face-widget-link)) - ((kill-local-variable 'erc-nicks--face-table) - (kill-local-variable 'erc-nicks--bg-mode-value) - (kill-local-variable 'erc-nicks--bg-luminance) - (kill-local-variable 'erc-nicks--fg-rgb) - (kill-local-variable 'erc-nicks--colors-len) - (kill-local-variable 'erc-nicks--colors-pool) - (kill-local-variable 'erc-nicks--downcased-skip-nicks) - (when (fboundp 'erc-button--phantom-users-mode) - (erc-button--phantom-users-mode -1)) - (remove-function (local 'erc-track--face-reject-function) - #'erc-nicks--reject-uninterned-faces) - (remove-function (local 'erc-button--modify-nick-function) - #'erc-nicks--highlight-button) - (remove-function (local 'erc-track--alt-normals-function) - #'erc-nicks--track-prioritize) - (remove-function (local 'erc-track--alt-normals-function) - #'erc-nicks--track-always) - (remove-hook 'erc-track-mode-hook #'erc-nicks--setup-track-integration t) - (setf (alist-get "Edit face" - erc-button--nick-popup-alist nil 'remove #'equal) - nil) - (unless erc-button--nick-popup-alist - (kill-local-variable 'erc-button--nick-popup-alist))) - localp) - -(defun erc-nicks-customize-face (nick) - "Customize or create persistent face for NICK." - (interactive (list (or (car (get-text-property (point) 'erc-data)) - (completing-read "nick: " (or erc-channel-users - erc-server-users))))) - (setq nick (erc-nicks--trim (substring-no-properties nick))) - (let* ((net (erc-network)) - (key (erc-nicks--gen-key-from-format-spec nick)) - (old-face (erc-nicks--get-face nick key)) - (new-face (intern (format "erc-nicks-%s@%s-face" nick net)))) - (unless (eq new-face old-face) - (erc-nicks--revive new-face old-face nick net) - (set-face-attribute old-face nil :foreground 'unspecified) - (set-face-attribute old-face nil :inherit new-face)) - (customize-face new-face))) - -(defun erc-nicks--list-faces-help-button-action (face) - (when-let (((or (get face 'erc-nicks--custom-face) - (y-or-n-p (format "Create new persistent face for %s?" - (get face 'erc-nicks--key))))) - (nid (get face 'erc-nicks--netid)) - (foundp (lambda () - (erc-networks--id-equal-p nid erc-networks--id))) - (server-buffer (car (erc-buffer-filter foundp)))) - (with-current-buffer server-buffer - (erc-nicks-customize-face (get face 'erc-nicks--nick))))) - -(defun erc-nicks-list-faces () - "Show faces owned by ERC-nicks in a help buffer." - (interactive) - (save-excursion - (list-faces-display (rx bot "erc-nicks-")) - (with-current-buffer "*Faces*" - (setq help-xref-stack nil - help-xref-stack-item '(erc-nicks-list-faces)) - (with-silent-modifications - (goto-char (point-min)) - (while (zerop (forward-line)) - (when (and (get-text-property (point) 'button) - (facep (car (button-get (point) 'help-args)))) - (button-put (point) 'help-function - #'erc-nicks--list-faces-help-button-action) - (if-let ((face (car (button-get (point) 'help-args))) - ((not (get face 'erc-nicks--custom-face))) - ((not (get face 'erc-nicks--key)))) - (progn (delete-region (pos-bol) (1+ (pos-eol))) - (forward-line -1)) - (when-let* ((nid (get face 'erc-nicks--netid)) - (net (erc-networks--id-string nid))) - (goto-char (button-end (point))) - (skip-syntax-forward "-") - (put-text-property (point) (1+ (point)) 'rear-nonsticky nil) - (forward-char) - (when (stringp (face-foreground face)) - (setq net (format "%-13.13s %s" (substring-no-properties - (face-foreground face)) - net))) - (insert-and-inherit net) - (delete-region (button-start (point)) - (1+ (button-start (point)))) - (delete-region (point) (pos-eol)))))))))) - -(defun erc-nicks-refresh (debug) - "Recompute faces for all nicks on current network. -With DEBUG (\\[universal-argument]), review affected faces or colors, -exactly which depends on the value of `erc-nicks-colors'. Expect users -to know that the list of rejected faces may include candidates that are -effectively duplicates because they map to already admitted ones." - (interactive "P") - (unless (derived-mode-p 'erc-mode) - (user-error "Not an ERC buffer")) - (erc-with-server-buffer - (unless erc-nicks-mode (user-error "Module `nicks' disabled")) - (let ((erc-nicks--colors-rejects (and debug (list t)))) - (erc-nicks--init-pool) - (unless erc-nicks--colors-pool - (user-error "Pool empty: all colors rejected")) - (dolist (nick (hash-table-keys erc-nicks--face-table)) - ;; User-tuned faces do not have an `erc-nicks--key' property. - (when-let ((face (gethash nick erc-nicks--face-table)) - (key (get face 'erc-nicks--key))) - (setq key (erc-nicks--gen-key-from-format-spec nick)) - (put face 'erc-nicks--key key) - (set-face-foreground face (erc-nicks--determine-color key)))) - (when debug - (if (eq erc-nicks-colors 'all) - (erc-nicks-list-faces) - (pcase-dolist (`(,name ,pool) - `(("*erc-nicks-pool*" ,erc-nicks--colors-pool) - ("*erc-nicks-rejects*" - ,(cdr (nreverse erc-nicks--colors-rejects))))) - (when (buffer-live-p (get-buffer name)) - (kill-buffer name)) - (when pool - (save-excursion - (list-colors-display - pool name - (lambda (c) - (message "contrast: %.3f :saturation: %.3f" - (erc-nicks--get-contrast c) - (cadr (apply #'color-rgb-to-hsl - (color-name-to-rgb c)))))))))))))) - -(defun erc-nicks--colors-from-faces (prefix) - "Extract foregrounds from faces with PREFIX -Expect PREFIX to be something like \"ansi-color-\" or \"font-lock-\"." - (let (out) - (dolist (face (face-list) (nreverse out)) - (when-let (((string-prefix-p prefix (symbol-name face))) - (color (face-foreground face))) - (push color out))))) - -(defun erc-nicks--reject-uninterned-faces (candidate) - "Remove own faces from CANDIDATE if it's a combination of faces." - (while-let ((next (car-safe candidate)) - ((facep next)) - ((not (intern-soft next)))) - (setq candidate (cdr candidate))) - (erc--solo candidate)) - -(define-inline erc-nicks--ours-p (face) - "Return uninterned `nicks'-created face if FACE is a known list of faces." - (inline-quote - (and-let* ((sym (car-safe ,face)) - ((symbolp sym)) - ((get sym 'erc-nicks--key))) - sym))) - -(defvar erc-nicks-track-normal-max-rank 'erc-default-face - "Highest priority normal face still eligible to alternate with `nicks' faces. -Must appear in both `erc-track-faces-priority-list' and -`erc-track-faces-normal-list'.") - -(defun erc-nicks--assess-track-faces (current contender ranks normals) - "Return symbol face for CURRENT or t, to mean CURRENT is replaceable. -But only do so if CURRENT and CONTENDER are either nil or \"normal\" -faces ranking at or below `erc-nicks-track-normal-max-rank'. See -`erc-track--select-mode-line-face' for the expected types of RANKS and -NORMALS. Expect a non-nil CONTENDER to always be ranked." - (and-let* - (((or (null contender) (gethash contender normals))) - ((or (null current) (gethash current normals))) - (threshold (gethash erc-nicks-track-normal-max-rank (car ranks))) - ((or (null contender) (<= threshold (gethash contender (car ranks))))) - ((or (erc-nicks--ours-p current) - (null current) - (<= threshold (or (gethash current (car ranks)) 0))))))) - -(defun erc-nicks--track-prioritize (current contender contenders ranks normals) - "Return a viable non-CURRENT `nicks' face among CONTENDERS. -See `erc-track--select-mode-line-face' for parameter types." - (when-let - ((spkr (erc-nicks--assess-track-faces current contender ranks normals))) - (catch 'contender - (dolist (candidate (cdr contenders)) - (when-let (((not (equal candidate current))) - (s (erc-nicks--ours-p candidate)) - ((not (eq s spkr)))) - (throw 'contender candidate)))))) - -(defun erc-nicks--track-always (current contender contenders ranks normals) - "Return a viable `nicks' face, possibly CURRENT, among CONTENDERS. -See `erc-track--select-mode-line-face' for parameter types." - (when (erc-nicks--assess-track-faces current contender ranks normals) - (catch 'contender - (dolist (candidate (reverse (cdr contenders))) - (when (erc-nicks--ours-p candidate) - (throw 'contender candidate)))))) - -(defun erc-nicks--setup-track-integration () - "Restore traditional \"alternating normal\" face functionality to mode-line." - (when (bound-and-true-p erc-track-mode) - (pcase erc-nicks-track-faces - ;; Variant `defer' is handled elsewhere. - ('prioritize - (add-function :override (local 'erc-track--alt-normals-function) - #'erc-nicks--track-prioritize)) - ('t - (add-function :override (local 'erc-track--alt-normals-function) - #'erc-nicks--track-always)) - ('nil - (add-function :override (local 'erc-track--face-reject-function) - #'erc-nicks--reject-uninterned-faces))))) - -(defun erc-nicks--remember-face-for-track (face) - "Add FACE to local hash table maintained by `track' module." - (or (gethash face erc-track--normal-faces) - (if-let ((sym (or (car-safe face) face)) - ((symbolp sym)) - ((get sym 'erc-nicks--key))) - (puthash face face erc-track--normal-faces) - face))) - -(provide 'erc-nicks) - -;;; erc-nicks.el ends here diff --git a/lisp/erc/erc-notify.el b/lisp/erc/erc-notify.el deleted file mode 100644 index af3fc6f46f3..00000000000 --- a/lisp/erc/erc-notify.el +++ /dev/null @@ -1,469 +0,0 @@ -;;; erc-notify.el --- Online status change notification -*- lexical-binding:t -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcNotify -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This module defines a new command, /NOTIFY -;; See the docstring of `erc-cmd-NOTIFY' for details. - -;;; Code: - -(require 'erc) -(eval-when-compile (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." - :type '(repeat string)) - -(defcustom erc-notify-interval 60 - "Time interval (in seconds) for checking online status of notified people." - :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." - :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." - :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-local erc-last-ison nil - "Last ISON information received through `erc-notify-timer'.") - -(defvar-local erc-last-ison-time 0 - "Last time ISON was sent to the server in `erc-notify-timer'.") - -;;;; Setup - -(defun erc-notify-install-message-catalogs () - (declare (obsolete "defined at top level in erc-notify.el" "30.1")) - (with-suppressed-warnings ((obsolete erc-define-catalog)) - (erc-define-catalog - 'english - '((notify-current . "Notified 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-server-connected - erc-notify-list - (> (erc-time-diff - erc-last-ison-time now) - erc-notify-interval)) - (erc-once-with-server-event - 303 - (lambda (proc parsed) - (let* ((server (erc-response.sender parsed)) - (ison-list (delete "" (split-string - (erc-response.contents parsed)))) - (new-list ison-list) - (old-list (erc-with-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'. -When that's the case, 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'. -When that's the case, 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'. -When that's the case, insert a `notify-off' message and remove -the nick from `erc-last-ison' to prevent 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 (cl-delete-if - (let ((nick-down (erc-downcase nick))) - (lambda (el) - (string= nick-down (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 notified people online, -with args, toggle notify status of people." - (unless erc-notify-mode - (erc-notify-mode +1) - (erc-button--display-error-notice-with-keys - (current-buffer) - "Command /NOTIFY requires the `notify' module. Enabling now. Add `notify'" - " to `erc-modules' before next starting ERC to silence this message.")) - (cond - ((null args) - ;; Print current notified people (online) - (let ((ison (erc-with-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") - (let ((list (if erc-notify-list - (mapconcat #'identity erc-notify-list " ") - "(empty)"))) - (erc-display-message nil 'notice 'active 'notify-list ?l 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 - ;; FIXME replace with `erc--server-buffer-p' or - ;; explain why that's unwise. - (if (erc-server-or-unjoined-channel-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-cmd-NOTIFY "-l"))) - t) - -;; "--" is not a typo. -(declare-function pcomplete--here "pcomplete" - (&optional form stub paring form-only)) -(declare-function pcomplete-erc-all-nicks "erc-pcomplete" - (&optional postfix)) - -;;;###autoload -(defun pcomplete/erc-mode/NOTIFY () - (require 'erc-pcomplete) - (pcomplete-here (append erc-notify-list (pcomplete-erc-all-nicks)))) - -(define-obsolete-variable-alias 'erc-message-english-notify_on - 'erc-message-english-notify-on "30.1") -(define-obsolete-variable-alias 'erc-message-english-notify_off - 'erc-message-english-notify-off "30.1") -(define-obsolete-variable-alias 'erc-message-english-notify_list - 'erc-message-english-notify-list "30.1") -(define-obsolete-variable-alias 'erc-message-english-notify_current - 'erc-message-english-notify-current "30.1") - -(erc-define-message-format-catalog english - (notify-current . "Notified 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")) - - -;;;; Module `querypoll' - -;; This module is similar to `notify' in that it periodically tries to -;; discover whether certain users are online. Unlike that module, it's -;; not really configurable. Rather, it only selects users you've -;; corresponded with in a query buffer, and it keeps `erc-server-users' -;; entries for them updated. - -(declare-function ring-empty-p "ring" (ring)) -(declare-function ring-insert "ring" (ring item)) -(declare-function ring-insert+extend "ring" (ring item)) -(declare-function ring-length "ring" (ring)) -(declare-function ring-member "ring" (ring item)) -(declare-function ring-ref "ring" (ring index)) -(declare-function ring-remove "ring" (ring &optional index)) - -(defvar-local erc--querypoll-ring nil) -(defvar-local erc--querypoll-timer nil) - -(defcustom erc-querypoll-exclude-regexp - (rx bot (or (: "*" (+ nonl)) (: (+ (in "A-Za-z")) "Serv")) eot) - "Pattern to skip polling for bots and services you regularly query." - :group 'erc - :package-version '(ERC . "5.6") - :type 'regexp) - -;;;###autoload(autoload 'erc-querypoll-mode "erc-notify" nil t) -(define-erc-module querypoll nil - "Send periodic \"WHO\" requests for each query buffer. -Omit query participants who are currently present in some channel. -Instead of announcing arrivals and departures, rely on other modules, -like `nickbar', to provide UI feedback when changes occur. - -Once ERC implements the `monitor' extension, this module will serve as -an optional fallback for keeping query-participant rolls up to date on -servers that lack support or are stingy with their allotments. Until -such time, this module should be considered experimental and only really -useful for bots and other non-interactive Lisp programs. - -This is a local ERC module, so selectively polling only a subset of -query targets is possible but cumbersome. To do so, ensure -`erc-querypoll-mode' is enabled in the server buffer, and then toggle it -as appropriate in desired query buffers. To stop polling for the -current connection, toggle off the command \\[erc-querypoll-mode] from a -server buffer, or run \\`M-x C-u erc-querypoll-disable RET' from a -target buffer. Note that this module's minor mode must remain active in -at least the server buffer." - ((if erc--target - (if (erc-query-buffer-p) - (progn ; accommodate those who eschew `erc-modules' - (erc-with-server-buffer - (unless erc-querypoll-mode - (erc-querypoll-mode +1))) - (erc--querypoll-subscribe (current-buffer))) - (erc-querypoll-mode -1)) - (cl-assert (not erc--decouple-query-and-channel-membership-p)) - (setq-local erc--querypoll-ring (make-ring 5)) - (erc-with-all-buffers-of-server erc-server-process nil - (unless erc-querypoll-mode - (erc-querypoll-mode +1))))) - ((when erc--querypoll-timer - (cancel-timer erc--querypoll-timer)) - (if erc--target - (when-let (((erc-query-buffer-p)) - (ring (erc-with-server-buffer erc--querypoll-ring)) - (index (ring-member ring (current-buffer))) - ((not (erc--querypoll-target-in-chan-p (current-buffer))))) - (ring-remove ring index) - (unless (erc-current-nick-p (erc-target)) - (erc-remove-current-channel-member (erc-target)))) - (erc-with-all-buffers-of-server erc-server-process #'erc-query-buffer-p - (erc-querypoll-mode -1))) - (kill-local-variable 'erc--querypoll-ring) - (kill-local-variable 'erc--querypoll-timer)) - localp) - -(cl-defmethod erc--queries-current-p (&context (erc-querypoll-mode (eql t))) t) - -(defvar erc-querypoll-period-params '(10 10 1) - "Parameters affecting the delay with respect to the number of buffers. -The elements represent some parameters of an exponential decay function, -a(e)^{-x/b}+c. The first number (a) affects the overall scaling. A -higher value means longer delays for all query buffers relative to queue -length. The second number (b) determines how quickly the delay -decreases as the queue length increases. Larger values make the delay -taper off more gradually. The last number (c) sets the minimum delay -between updates regardless of queue length.") - -(defun erc--querypoll-compute-period (queue-size) - "Calculate delay based on QUEUE-SIZE." - (let ((scale (nth 0 erc-querypoll-period-params)) - (rate (* 1.0 (nth 1 erc-querypoll-period-params))) - (min (nth 2 erc-querypoll-period-params))) - (+ (* scale (exp (/ (- queue-size) rate))) min))) - -(defun erc--querypoll-target-in-chan-p (buffer) - "Determine whether buffer's target, as a user, is joined to any channels." - (and-let* - ((target (erc--target-string (buffer-local-value 'erc--target buffer))) - (user (erc-get-server-user target)) - (buffers (erc-server-user-buffers user)) - ((seq-some #'erc-channel-p buffers))))) - -(defun erc--querypoll-get-length (ring) - "Return the effective length of RING, discounting chan members." - (let ((count 0)) - (dotimes (i (ring-length ring)) - (unless (erc--querypoll-target-in-chan-p (ring-ref ring i)) - (cl-incf count 1))) - count)) - -(defun erc--querypoll-get-next (ring) - (let ((n (ring-length ring))) - (catch 'found - (while (natnump (cl-decf n)) - (when-let ((buffer (ring-remove ring)) - ((buffer-live-p buffer))) - ;; Push back buffers for users joined to some chan. - (if (erc--querypoll-target-in-chan-p buffer) - (ring-insert ring buffer) - (throw 'found buffer))))))) - -(defun erc--querypoll-subscribe (query-buffer &optional penalty) - "Add QUERY-BUFFER to FIFO and ensure timer is running." - (when query-buffer - (cl-assert (erc-query-buffer-p query-buffer))) - (erc-with-server-buffer - (when (and query-buffer - (not (with-current-buffer query-buffer - (or (erc-current-nick-p (erc-target)) - (string-match erc-querypoll-exclude-regexp - (erc-target))))) - (not (ring-member erc--querypoll-ring query-buffer))) - (ring-insert+extend erc--querypoll-ring query-buffer)) - (unless erc--querypoll-timer - (setq erc--querypoll-timer - (let* ((length (erc--querypoll-get-length erc--querypoll-ring)) - (period (erc--querypoll-compute-period length))) - (run-at-time (+ (or penalty 0) period) - nil #'erc--querypoll-send (current-buffer))))))) - -(defun erc--querypoll-on-352 (target-nick args) - "Add or update `erc-server-users' data for TARGET-NICK from ARGS. -Then add user to participant rolls in any existing query buffers." - (pcase-let - ((`(,_ ,channel ,login ,host ,_server ,nick ,_flags, hop-real) args)) - (when (and (string= channel "*") (erc-nick-equal-p nick target-nick)) - (if-let ((user (erc-get-server-user nick))) - (erc-update-user user nick host login - (erc--extract-352-full-name hop-real)) - ;; Don't add unless target is already known. - (when (erc-get-buffer nick erc-server-process) - (erc-add-server-user - nick (make-erc-server-user - :nickname nick :login login :host host - :full-name (erc--extract-352-full-name hop-real))))) - (erc--ensure-query-member nick) - t))) - -;; This uses heuristics to associate replies to the initial request -;; because ERC does not yet support `labeled-response'. -(defun erc--querypoll-send (server-buffer) - "Send a captive \"WHO\" in SERVER-BUFFER." - (when (and (buffer-live-p server-buffer) - (buffer-local-value 'erc-server-connected server-buffer)) - (with-current-buffer server-buffer - (setq erc--querypoll-timer nil) - (if-let ((buffer (erc--querypoll-get-next erc--querypoll-ring))) - (letrec - ((target (erc--target-string - (buffer-local-value 'erc--target buffer))) - (penalty 0) - (here-fn (erc-once-with-server-event - "352" (lambda (_ parsed) - (erc--querypoll-on-352 - target (erc-response.command-args parsed))))) - (done-fn (erc-once-with-server-event - "315" - (lambda (_ parsed) - (if (memq here-fn erc-server-352-functions) - (erc-remove-user - (nth 1 (erc-response.command-args parsed))) - (remove-hook 'erc-server-352-functions here-fn t)) - (remove-hook 'erc-server-263-functions fail-fn t) - (remove-hook 'erc-server-315-functions done-fn t) - (erc--querypoll-subscribe buffer penalty) - t))) - (fail-fn (erc-once-with-server-event - "263" - (lambda (proc parsed) - (setq penalty 60) - (funcall done-fn proc parsed) - t)))) - (erc-server-send (concat "WHO " target))) - (unless (ring-empty-p erc--querypoll-ring) - (erc--querypoll-subscribe nil 30)))))) - -(provide 'erc-notify) - -;;; erc-notify.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-page.el b/lisp/erc/erc-page.el deleted file mode 100644 index 8814bcd8228..00000000000 --- a/lisp/erc/erc-page.el +++ /dev/null @@ -1,114 +0,0 @@ -;;; erc-page.el --- CTCP PAGE support for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2002, 2004, 2006-2025 Free Software Foundation, Inc. - -;; Maintainer: Amin Bandali , F. Jason Park - -;; 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 3 of the License, 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. If not, see . - -;;; 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) - -(declare-function erc-controls-interpret "erc-goodies" (str)) - -(defgroup erc-page nil - "React to CTCP PAGE messages." - :group 'erc) - -;;;###autoload(put 'ctcp-page 'erc--module 'page) -;;;###autoload(autoload 'erc-page-mode "erc-page") -(define-erc-module page ctcp-page - "Process CTCP PAGE requests from IRC." - nil nil) - -(defvar erc-message-english-CTCP-PAGE "Page from %n (%u@%h): %m" - "English template for a CTCP PAGE message.") - -(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 init 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)))" - :type '(choice (const nil) - (function))) - -(defcustom erc-ctcp-query-PAGE-hook (list #'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." - :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." - (require 'erc-goodies) ; for `erc-controls-interpret' - (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) - -;;; erc-page.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-pcomplete.el b/lisp/erc/erc-pcomplete.el deleted file mode 100644 index b91f213a723..00000000000 --- a/lisp/erc/erc-pcomplete.el +++ /dev/null @@ -1,298 +0,0 @@ -;;; erc-pcomplete.el --- Provides programmable completion for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Sacha Chua -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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 'time-date) - -(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." - :type 'string) - -(defcustom erc-pcomplete-order-nickname-completions t - "If t, order nickname completions with the most recent speakers first." - :type 'boolean) - -;;;###autoload(put 'Completion 'erc--module 'completion) -;;;###autoload(put 'pcomplete 'erc--module 'completion) -;;;###autoload(put 'completion 'erc--feature 'erc-pcomplete) -;;;###autoload(autoload 'erc-completion-mode "erc-pcomplete" nil t) -(put 'completion 'erc-group 'erc-pcomplete) -(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-pcompletions-at-point) - (erc-buffer-list #'pcomplete-erc-setup)) - ((remove-hook 'erc-mode-hook #'pcomplete-erc-setup) - (remove-hook 'erc-complete-functions #'erc-pcompletions-at-point))) - -(defun erc-pcompletions-at-point () - "ERC completion data from pcomplete. -for use on `completion-at-point-function'." - (when (> (point) (erc-beg-of-input-line)) - (or (let ((pcomplete-default-completion-function #'ignore)) - (pcomplete-completions-at-point)) - (let ((c (pcomplete-completions-at-point))) - (if c (nconc c '(:exclusive no))))))) - -(defun erc-pcomplete () - "Complete the nick before point." - (declare (obsolete completion-at-point "25.1")) - (interactive) - (when (> (point) (erc-beg-of-input-line)) - (let ((completion-at-point-functions '(erc-pcompletions-at-point))) - (completion-at-point)))) - -;;; Setup function - -(defun pcomplete-erc-setup () - "Setup `erc-mode' to use pcomplete." - (setq-local completion-ignore-case t) - (setq-local pcomplete-use-paring nil) - (setq-local pcomplete-parse-arguments-function - #'pcomplete-erc-parse-arguments) - (setq-local pcomplete-command-completion-function - #'pcomplete/erc-mode/complete-command) - (setq-local pcomplete-command-name-function - #'pcomplete-erc-command-name) - (setq-local 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 t)))) - -(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 (erc-with-server-buffer erc-ignore-list))) - -(defun pcomplete/erc-mode/RECONNECT () - (pcomplete-here '("cancel")) - (pcomplete-opt "a")) - -(defun pcomplete/erc-mode/BANLIST () - (pcomplete-opt "f")) -(defalias 'pcomplete/erc-mode/BL #'pcomplete/erc-mode/BANLIST) - -(defun pcomplete/erc-mode/MASSUNBAN () - (pcomplete-opt "f")) -(defalias 'pcomplete/erc-mode/MUB #'pcomplete/erc-mode/MASSUNBAN) - -;;; Functions that provide possible completions. - -(defun pcomplete-erc-commands () - "Return 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 () - "Return 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 () - "Return 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 ignore-self) - "Return a list of nicks in the current channel. -Optional argument POSTFIX is something to append to the nickname. -If optional argument IGNORE-SELF is non-nil, don't return the current nick." - (let ((users (if erc-pcomplete-order-nickname-completions - (erc-sort-channel-users-by-activity - (erc-get-channel-user-list)) - (erc-get-channel-user-list))) - (nicks nil)) - (dolist (user users) - (unless (or (not user) - (and ignore-self - (string= (erc-server-user-nickname (car user)) - (erc-current-nick)))) - (setq nicks (cons (concat (erc-server-user-nickname (car user)) - postfix) - nicks)))) - (nreverse nicks))) - -(defun pcomplete-erc-all-nicks (&optional postfix) - "Return a list of all nicks on the current server." - (let (nicks) - (erc-with-server-buffer - (maphash (lambda (_nick user) - (setq nicks (cons - (concat (erc-server-user-nickname user) postfix) - nicks))) - erc-server-users)) - nicks)) - -(defun pcomplete-erc-channels () - "Return 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 () - "Return the command name of the first argument." - (if (eq (elt (pcomplete-arg 'first) 0) ?/) - (upcase (substring (pcomplete-arg 'first) 1)) - "SAY")) - -(defun pcomplete-erc-parse-arguments () - "Return 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: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-replace.el b/lisp/erc/erc-replace.el deleted file mode 100644 index e95761e2364..00000000000 --- a/lisp/erc/erc-replace.el +++ /dev/null @@ -1,93 +0,0 @@ -;;; erc-replace.el --- wash and massage messages inserted into the buffer -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2025 Free Software Foundation, Inc. - -;; Author: Andreas Fuchs -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcReplace -;; Keywords: comm, IRC, 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This module allows you to systematically replace text in incoming -;; messages. Load erc-replace, and customize `erc-replace-alist'. -;; Then add to your init file: - -;; (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." - :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 t))) - (while (re-search-forward from nil t) - (cond ((stringp to) - (replace-match to)) - ((functionp to) - (replace-match (funcall to (match-string 0)))) - (t - (eval to t)))))) - 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) - -;;; erc-replace.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-ring.el b/lisp/erc/erc-ring.el deleted file mode 100644 index 2a914b7657b..00000000000 --- a/lisp/erc/erc-ring.el +++ /dev/null @@ -1,150 +0,0 @@ -;;; erc-ring.el --- Command history handling for erc using ring.el -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Alex Schroeder -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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) - -(defgroup erc-ring nil - "An input ring for ERC." - :group 'erc) - -;;;###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--input-review-functions #'erc-add-to-input-ring 90) - (define-key erc-mode-map "\M-p" #'erc-previous-command) - (define-key erc-mode-map "\M-n" #'erc-next-command)) - ((remove-hook 'erc--input-review-functions #'erc-add-to-input-ring) - (define-key erc-mode-map "\M-p" #'undefined) - (define-key erc-mode-map "\M-n" #'undefined))) - -(defvar-local erc-input-ring nil "Input ring for erc.") - -(defvar-local 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.") - -(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." - (unless (ring-p erc-input-ring) - (setq erc-input-ring (make-ring comint-input-ring-size))) - (setq erc-input-ring-index nil)) - -(defun erc-add-to-input-ring (state-or-string) - "Add STATE-OR-STRING to input ring and reset history position. -STATE-OR-STRING should be a string or an erc-input object." - (unless erc-input-ring (erc-input-ring-setup)) - (ring-insert erc-input-ring (if (erc-input-p state-or-string) - (erc-input-string state-or-string) - state-or-string)) ; string - (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. - (when (and (null erc-input-ring-index) - (> (point-max) erc-input-marker)) - (erc-add-to-input-ring (erc-user-input)) - (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: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-sasl.el b/lisp/erc/erc-sasl.el deleted file mode 100644 index f311255dfbb..00000000000 --- a/lisp/erc/erc-sasl.el +++ /dev/null @@ -1,440 +0,0 @@ -;;; erc-sasl.el --- SASL for ERC -*- lexical-binding: t -*- - -;; Copyright (C) 2022-2025 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 3 of the License, -;; 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. If not, see . - -;;; Commentary: - -;; This "non-IRCv3" implementation resembles others that have surfaced -;; over the years, the first possibly being from Joseph Gay: -;; -;; https://lists.gnu.org/archive/html/erc-discuss/2012-02/msg00001.html -;; -;; See M-x customize-group RET erc-sasl RET and (info "(erc) SASL") -;; for usage. -;; -;; TODO: -;; -;; - Obfuscate non-auth-source passwords in memory. They're currently -;; visible in backtraces. -;; -;; - Implement a proxy mechanism that chooses the strongest available -;; mechanism for you. Requires CAP 3.2 (see bug#49860). - -;;; Code: -(require 'erc) -(require 'rx) -(require 'sasl) -(require 'sasl-scram-rfc) -(require 'sasl-scram-sha256 nil t) ; not present in Emacs 27 - -(defgroup erc-sasl nil - "SASL for ERC." - :group 'erc - :package-version '(ERC . "5.5")) - -(defcustom erc-sasl-mechanism 'plain - "SASL mechanism to connect with. -Note that any value other than nil or `external' likely requires -`erc-sasl-user' and `erc-sasl-password'." - :type '(choice (const plain) - (const external) - (const scram-sha-1) - (const scram-sha-256) - (const scram-sha-512) - (const ecdsa-nist256p-challenge))) - -(defcustom erc-sasl-user :user - "Account username to send when authenticating. -This option specifies the SASL authentication identity, or -\"authcid\". A value of `:user' or `:nick' indicates that the -corresponding connection parameter on file should be used. ERC -typically obtains these from arguments given to its entry-point -commands, `erc' and `erc-tls'." - :type '(choice string (const :user) (const :nick))) - -(defcustom erc-sasl-password :password - "Optional account password to send when authenticating. -When `erc-sasl-auth-source-function' is a function, ERC attempts -an auth-source query and prompts for input if it fails. -Otherwise, when the value of this option is a nonempty string, -ERC uses it unconditionally for most mechanisms. Likewise with a -value of `:password', except ERC instead uses the \"session -password\" on file, if any, which often originates from the -entry-point commands `erc' or `erc-tls'. As with auth-source, -ERC prompts for input as a fallback. - -Note that, with `:password', ERC forgoes sending a traditional -server password via the IRC \"PASS\" command. Also, when -`erc-sasl-mechanism' is set to `ecdsa-nist256p-challenge', ERC -expects this option to hold the file name of the key." - :type '(choice (const nil) (const :password) string symbol)) - -(defcustom erc-sasl-auth-source-function nil - "Function to query auth-source for an SASL password. -If provided, this function should expect to be called with any -number of keyword params known to `auth-source-search', even -though ERC itself only specifies `:user' paired with a -\"resolved\" `erc-sasl-user' value. When calling this function, -ERC binds all options defined in this library, such as -`erc-sasl-password', to their values from entry-point invocation. -In return, ERC expects a string to send as the SASL password, or -nil, in which case, ERC prompts for input. See Info node `(erc) -auth-source' for details on ERC's auth-source integration." - :type '(choice (function-item erc-sasl-auth-source-password-as-host) - (function-item erc-auth-source-search) - (const nil) - function)) - -(defcustom erc-sasl-authzid nil - "SASL authorization identity, likely unneeded for everyday use." - :type '(choice (const nil) string)) - - -;; Analogous to what erc-backend does to persist opening params. -(defvar-local erc-sasl--options nil) - -;; Session-local (server buffer) SASL subproto state -(defvar-local erc-sasl--state nil) - -(cl-defstruct erc-sasl--state - "Holder for client object and subproto state." - (client nil :type vector) - (step nil :type vector) - (pending nil :type string)) - -(defun erc-sasl--get-user () - (pcase (alist-get 'user erc-sasl--options) - (:user erc-session-username) - (:nick (erc-current-nick)) - (v v))) - -(defun erc-sasl-auth-source-password-as-host (&rest plist) - "Call `erc-auth-source-search' with `erc-sasl-password' as `:host'. -But only do so when it's a string or a non-nil symbol, unless -that symbol is `:password', in which case, use a non-nil -`erc-session-password' instead. Otherwise, just defer to -`erc-auth-source-search' to pick a suitable `:host'. Expect -PLIST to contain keyword params known to `auth-source-search'." - (when-let* ((erc-sasl-password) - (host (if (eq :password erc-sasl-password) - (and (not (functionp erc-session-password)) - erc-session-password) - erc-sasl-password))) - (setq plist `(,@plist :host ,(format "%s" host)))) - (apply #'erc-auth-source-search plist)) - -(defun erc-sasl--read-password (prompt) - "Return configured option or server password. -If necessary, pass PROMPT to `read-passwd'." - (if-let ((found (pcase (alist-get 'password erc-sasl--options) - ((guard (alist-get 'authfn erc-sasl--options)) - (let-alist erc-sasl--options - (let ((erc-sasl-user .user) - (erc-sasl-password .password) - (erc-sasl-mechanism .mechanism) - (erc-sasl-authzid .authzid) - (erc-sasl-auth-source-function .authfn)) - (funcall .authfn :user (erc-sasl--get-user))))) - (:password erc-session-password) - ((and (pred stringp) v) (unless (string-empty-p v) v))))) - (copy-sequence (erc--unfun found)) - (read-passwd prompt))) - -(defun erc-sasl--plain-response (client steps) - (let ((sasl-read-passphrase #'erc-sasl--read-password)) - (sasl-plain-response client steps))) - -(declare-function erc-compat--29-sasl-scram--client-final-message "erc-compat" - (hash-fun block-length hash-length client step)) - -(defun erc-sasl--scram-sha-hack-client-final-message (&rest args) - ;; In the future (29+), we'll hopefully be able to call - ;; `sasl-scram--client-final-message' directly - (require 'erc-compat) - (let ((sasl-read-passphrase #'erc-sasl--read-password)) - (apply #'erc-compat--29-sasl-scram--client-final-message args))) - -(defun erc-sasl--scram-sha-1-client-final-message (client step) - (erc-sasl--scram-sha-hack-client-final-message 'sha1 64 20 client step)) - -(defun erc-sasl--scram-sha-256-client-final-message (client step) - (erc-sasl--scram-sha-hack-client-final-message 'sasl-scram-sha256 64 32 - client step)) - -(defun erc-sasl--scram-sha512 (object &optional start end binary) - (secure-hash 'sha512 object start end binary)) - -(defun erc-sasl--scram-sha-512-client-final-message (client step) - (erc-sasl--scram-sha-hack-client-final-message #'erc-sasl--scram-sha512 - 128 64 client step)) - -(defun erc-sasl--scram-sha-512-authenticate-server (client step) - (sasl-scram--authenticate-server #'erc-sasl--scram-sha512 - 128 64 client step)) - -(defun erc-sasl--ecdsa-first (client _step) - "Return CLIENT name." - (sasl-client-name client)) - -;; FIXME do this with gnutls somehow -(defun erc-sasl--ecdsa-sign (client step) - "Return signed challenge for CLIENT and current STEP." - (let ((challenge (sasl-step-data step))) - (with-temp-buffer - (set-buffer-multibyte nil) - (insert challenge) - (call-process-region (point-min) (point-max) - "openssl" 'delete t nil "pkeyutl" "-inkey" - (sasl-client-property client 'ecdsa-keyfile) - "-sign") - (buffer-string)))) - -(pcase-dolist - (`(,name . ,steps) - '(("PLAIN" - erc-sasl--plain-response) - ("EXTERNAL" - ignore) - ("SCRAM-SHA-1" - erc-compat--29-sasl-scram-client-first-message - erc-sasl--scram-sha-1-client-final-message - sasl-scram-sha-1-authenticate-server) - ("SCRAM-SHA-256" - erc-compat--29-sasl-scram-client-first-message - erc-sasl--scram-sha-256-client-final-message - sasl-scram-sha-256-authenticate-server) - ("SCRAM-SHA-512" - erc-compat--29-sasl-scram-client-first-message - erc-sasl--scram-sha-512-client-final-message - erc-sasl--scram-sha-512-authenticate-server) - ("ECDSA-NIST256P-CHALLENGE" - erc-sasl--ecdsa-first - erc-sasl--ecdsa-sign))) - (let ((feature (intern (concat "erc-sasl-" (downcase name))))) - (put feature 'sasl-mechanism (sasl-make-mechanism name steps)) - (provide feature))) - -(cl-defgeneric erc-sasl--create-client (mechanism) - "Create and return a new SASL client object for MECHANISM." - (let ((sasl-mechanism-alist (copy-sequence sasl-mechanism-alist)) - (sasl-mechanisms sasl-mechanisms) - (name (upcase (symbol-name mechanism))) - (feature (intern-soft (concat "erc-sasl-" (symbol-name mechanism)))) - client) - (when feature - (setf (alist-get name sasl-mechanism-alist nil nil #'equal) `(,feature)) - (cl-pushnew name sasl-mechanisms :test #'equal) - (setq client (sasl-make-client (sasl-find-mechanism (list name)) - (erc-sasl--get-user) - "N/A" "N/A")) - (sasl-client-set-property client 'authenticator-name - (alist-get 'authzid erc-sasl--options)) - client))) - -(cl-defmethod erc-sasl--create-client ((_ (eql plain))) - "Create and return a new PLAIN client object." - ;; https://tools.ietf.org/html/rfc4616#section-2. - (let* ((sans (remq (assoc "PLAIN" sasl-mechanism-alist) - sasl-mechanism-alist)) - (sasl-mechanism-alist (cons '("PLAIN" erc-sasl-plain) sans)) - (authc (erc-sasl--get-user)) - (port (if (numberp erc-session-port) - (number-to-string erc-session-port) - "0")) - ;; In most cases, `erc-server-announced-name' won't be known. - (host (or erc-server-announced-name erc-session-server)) - (mech (sasl-find-mechanism '("PLAIN"))) - (client (sasl-make-client mech authc port host))) - (sasl-client-set-property client 'authenticator-name - (alist-get 'authzid erc-sasl--options)) - client)) - -(cl-defmethod erc-sasl--create-client ((_ (eql scram-sha-256))) - "Create and return a new SCRAM-SHA-256 client." - (when (featurep 'sasl-scram-sha256) - (cl-call-next-method))) - -(cl-defmethod erc-sasl--create-client ((_ (eql scram-sha-512))) - "Create and return a new SCRAM-SHA-512 client." - (when (featurep 'sasl-scram-sha256) - (cl-call-next-method))) - -(cl-defmethod erc-sasl--create-client ((_ (eql ecdsa-nist256p-challenge))) - "Create and return a new ECDSA-NIST256P-CHALLENGE client." - (let ((keyfile (cdr (assq 'password erc-sasl--options)))) - ;; Better to signal usage errors now than inside a process filter. - (cond ((or (not (stringp keyfile)) (not (file-readable-p keyfile))) - (erc-display-error-notice - nil "`erc-sasl-password' not accessible as a file") - nil) - ((not (executable-find "openssl")) - (erc-display-error-notice nil "Could not find openssl program") - nil) - (t - (let ((client (cl-call-next-method))) - (sasl-client-set-property client 'ecdsa-keyfile keyfile) - client))))) - -(defun erc-sasl--mechanism-offered-p (offered) - "Return non-nil when OFFERED appears among a list of mechanisms." - (string-match-p (rx-to-string - `(: (| bot ",") - ,(symbol-name (alist-get 'mechanism erc-sasl--options)) - (| eot ","))) - (downcase offered))) - -(erc--define-catalog english - ((s902 . "ERR_NICKLOCKED nick %n unavailable: %s") - (s904 . "ERR_SASLFAIL (authentication failed) %s") - (s905 . "ERR SASLTOOLONG (credentials too long) %s") - (s906 . "ERR_SASLABORTED (authentication aborted) %s") - (s907 . "ERR_SASLALREADY (already authenticated) %s") - (s908 . "RPL_SASLMECHS (unsupported mechanism: %m) %s"))) - -(define-erc-module sasl nil - "Non-IRCv3 SASL support for ERC. -This local module only enables its minor mode in server buffers, and it -doesn't currently solicit or validate supported mechanisms." - ((if erc--target - (erc-sasl-mode -1) - (setq erc-sasl--state (make-erc-sasl--state)) - ;; If the previous attempt failed during registration, this may be - ;; non-nil and contain erroneous values, but how can we detect that? - ;; What if the server dropped the connection for some other reason? - (erc--restore-initialize-priors erc-sasl-mode - erc-sasl--options `((user . ,erc-sasl-user) - (password . ,erc-sasl-password) - (mechanism . ,erc-sasl-mechanism) - (authfn . ,erc-sasl-auth-source-function) - (authzid . ,erc-sasl-authzid))) - (let* ((mech (alist-get 'mechanism erc-sasl--options)) - (client (erc-sasl--create-client mech))) - (unless client - (erc-display-error-notice - nil (format "Unknown or unsupported SASL mechanism: `%s'" mech)) - (error "Unknown or unsupported SASL mechanism: `%s'" mech)) - (setf (erc-sasl--state-client erc-sasl--state) client)))) - ((kill-local-variable 'erc-sasl--state) - (kill-local-variable 'erc-sasl--options)) - localp) - -(define-erc-response-handler (AUTHENTICATE) - "Begin or resume an SASL session." nil - (if-let* ((response (car (erc-response.command-args parsed))) - ((= 400 (length response)))) - (cl-callf (lambda (s) (concat s response)) - (erc-sasl--state-pending erc-sasl--state)) - (cl-assert response t) - (when (string= "+" response) - (setq response "")) - (setf response (base64-decode-string - (concat (erc-sasl--state-pending erc-sasl--state) - response)) - (erc-sasl--state-pending erc-sasl--state) nil) - (let ((client (erc-sasl--state-client erc-sasl--state)) - (step (erc-sasl--state-step erc-sasl--state)) - data) - (when step - (sasl-step-set-data step response)) - (setq step (setf (erc-sasl--state-step erc-sasl--state) - (sasl-next-step client step)) - data (sasl-step-data step)) - (when (string= data "") - (setq data nil)) - (setq data (if data (erc--unfun (base64-encode-string data t)) "+")) - (while (not (string-empty-p data)) - (let ((end (min 400 (length data)))) - ;; For now, assume this is unlikely to block - (erc-server-send (concat "AUTHENTICATE " (substring data 0 end))) - (setq data (concat (substring data end) (and (= end 400) "+")))))))) - -(defun erc-sasl--destroy (proc) - "Destroy process PROC and warn user that their settings are likely faulty." - (delete-process proc) - (erc--lwarn 'erc-sasl :error - "Disconnected from %s; please review SASL settings" proc) - nil) - -(define-erc-response-handler (902) - "Handle an ERR_NICKLOCKED response." nil - (erc-display-message parsed '(notice error) 'active 's902 - ?n (car (erc-response.command-args parsed)) - ?s (erc-response.contents parsed)) - (erc-sasl--destroy proc)) - -(define-erc-response-handler (903) - "Handle a RPL_SASLSUCCESS response." nil - (when erc-sasl-mode - (unless erc-server-connected - (erc-server-send "CAP END"))) - (erc-display-message parsed 'notice proc (erc-response.contents parsed))) - -(define-erc-response-handler (907) - "Handle a RPL_SASLALREADY response." nil - (erc-display-message parsed '(notice error) 'active 's907 - ?s (erc-response.contents parsed))) - -(define-erc-response-handler (904 905 906) - "Handle various SASL-related error responses." nil - (erc-display-message parsed '(notice error) 'active - (intern (format "s%s" (erc-response.command parsed))) - ?s (erc-response.contents parsed)) - (erc-sasl--destroy proc)) - -(define-erc-response-handler (908) - "Handle a RPL_SASLMECHS response." nil - (erc-display-message parsed '(notice error) 'active 's908 - ?m (alist-get 'mechanism erc-sasl--options) - ?s (string-join (cdr (erc-response.command-args parsed)) - " ")) - (erc-sasl--destroy proc)) - -(defvar erc-sasl--send-cap-ls nil - "Whether to send an opening \"CAP LS\" command. -This is an escape hatch for picky servers. If you need it turned -into a user option, please let ERC know via \\[erc-bug]. -Otherwise, expect it to disappear in subsequent versions.") - -(cl-defmethod erc--register-connection (&context (erc-sasl-mode (eql t))) - "Send speculative CAP and pipelined AUTHENTICATE and hope for the best." - (if-let* ((c (erc-sasl--state-client erc-sasl--state)) - (m (sasl-mechanism-name (sasl-client-mechanism c)))) - (progn - (erc-server-send (if erc-sasl--send-cap-ls "CAP LS" "CAP REQ :sasl")) - (let ((erc-session-password - (and erc-session-password - (not (eq :password - (alist-get 'password erc-sasl--options))) - erc-session-password)) - (erc-session-username - ;; The username may contain a colon or a space - (if (eq :user (alist-get 'user erc-sasl--options)) - (erc-current-nick) - erc-session-username))) - (cl-call-next-method)) - (when erc-sasl--send-cap-ls - (erc-server-send "CAP REQ :sasl")) - (erc-server-send (format "AUTHENTICATE %s" m))) - (erc-sasl--destroy erc-server-process))) - -(provide 'erc-sasl) -;;; erc-sasl.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-services.el b/lisp/erc/erc-services.el deleted file mode 100644 index b10504dd306..00000000000 --- a/lisp/erc/erc-services.el +++ /dev/null @@ -1,665 +0,0 @@ -;;; erc-services.el --- Identify to NickServ -*- lexical-binding:t -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcNickserv - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; As of ERC 5.6, this library's main module, `services', mainly -;; concerns itself with authenticating to legacy IRC servers. If your -;; server supports SASL or CERTFP, please use one of those instead. -;; See (info "(erc) client-certificate") and (info "(erc) SASL") for -;; details. Note that this library also contains the local module -;; `services-regain' as well as standalone utility functions. - -;; 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, -;; GRnet, Libera.Chat, and Slashnet. You can add more by using -;; M-x customize-variable RET erc-nickserv-alist. - -;; Usage: -;; -;; Customize the option `erc-modules' to include `services'. -;; -;; Add your nickname and NickServ password to `erc-nickserv-passwords'. -;; Using the Libera.Chat network as an example: -;; -;; (setq erc-nickserv-passwords -;; '((Libera.Chat (("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. -;; -;; 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-networks) -(eval-when-compile (require 'cl-lib)) - -;; 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) - -(defcustom erc-nickserv-identify-mode 'both - "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 log in or change your nickname. -`both' - Do the former if the network supports it, otherwise do the - latter. -nil - Disables automatic Nickserv identification. - -You can also use \\[erc-nickserv-identify-mode] to change modes." - :type '(choice (const autodetect) - (const nick-change) - (const both) - (const nil)) - :set (lambda (sym val) - (set sym val) - ;; avoid recursive load at startup - (when (featurep 'erc-services) - (erc-nickserv-identify-mode val)))) - -;;;###autoload(put 'nickserv 'erc--module 'services) -;;;###autoload(autoload 'erc-services-mode "erc-services" 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) - (remove-hook 'erc-server-NOTICE-functions - #'erc-nickserv-identification-autodetect))) - -;;;###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") ("both")) nil t)))) - (add-hook 'erc-server-NOTICE-functions - #'erc-nickserv-identification-autodetect) - (unless erc-networks-mode - ;; Force-enable networks module, because we need it to set - ;; erc-network for us. - (erc-networks-enable)) - (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)) - ((eq mode 'both) - (setq erc-nickserv-identify-mode 'both) - (add-hook 'erc-server-NOTICE-functions - #'erc-nickserv-identify-autodetect) - (add-hook 'erc-after-connect - #'erc-nickserv-identify-on-connect) - (add-hook 'erc-nick-changed-functions - #'erc-nickserv-identify-on-nick-change)) - (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) - (remove-hook 'erc-server-NOTICE-functions - #'erc-nickserv-identification-autodetect)))) - -(defcustom erc-prompt-for-nickserv-password t - "Ask for the password when identifying to NickServ." - :type 'boolean) - -(defcustom erc-use-auth-source-for-nickserv-password nil - "Query auth-source for a password when identifying to NickServ. -Passwords from `erc-nickserv-passwords' take precedence. See -function `erc-nickserv-get-password'." - :version "28.1" - :type 'boolean) - -(defcustom erc-auth-source-services-function #'erc-auth-source-search - "Function to retrieve NickServ password from auth-source. -Called with a subset of keyword parameters known to -`auth-source-search' and relevant to authenticating to nickname -services. In return, ERC expects a string to send as the -password, or nil, to fall through to the next method, such as -prompting. See Info node `(erc) auth-source' for details." - :package-version '(ERC . "5.5") - :type '(choice (function-item erc-auth-source-search) - (const nil) - function)) - -(defcustom erc-nickserv-passwords nil - "Passwords used when identifying to NickServ automatically. -`erc-prompt-for-nickserv-password' must be nil for these -passwords to be used. - -Example of use: - (setq erc-nickserv-passwords - \\='((Libera.Chat ((\"nick-one\" . \"password\") - (\"nick-two\" . \"password\"))) - (DALnet ((\"nick\" . \"password\")))))" - :type '(repeat - (list :tag "Network" - (choice :tag "Network name" - (const Ars) - (const Austnet) - (const Azzurra) - (const BitlBee) - (const BRASnet) - (const DALnet) - (const freenode) - (const GalaxyNet) - (const GRnet) - (const iip) - (const Libera.Chat) - (const OFTC) - (const QuakeNet) - (const Rizon) - (const SlashNET) - (symbol :tag "Network name or session ID")) - (repeat :tag "Nickname and password" - (cons :tag "Identity" - (string :tag "Nick") - (string :tag "Password" - :secret ?*)))))) - -;; Variables: - -(defcustom erc-nickserv-alist - '((Ars - nil nil - "Census" - "IDENTIFY" nil nil nil) - (Austnet - "NickOP!service@austnet.org" - "/msg\\s-NickOP@austnet.org\\s-identify\\s-" - "nickop@austnet.org" - "identify" nil nil nil) - (Azzurra - "NickServ!service@azzurra.org" - "\^B/ns\\s-IDENTIFY\\s-password\^B" - "NickServ" - "IDENTIFY" nil nil nil) - (BitlBee - nil nil - "&bitlbee" - "identify" nil nil nil) - (BRASnet - "NickServ!services@brasnet.org" - "\^B/NickServ\\s-IDENTIFY\\s-\^_senha\^_\^B" - "NickServ" - "IDENTIFY" nil "" nil) - (DALnet - "NickServ!service@dal.net" - "/msg\\s-NickServ@services.dal.net\\s-IDENTIFY\\s-" - "NickServ@services.dal.net" - "IDENTIFY" nil nil nil) - (freenode - "NickServ!NickServ@services." - ;; freenode also accepts a password at login, see the `erc' - ;; :password argument. - "This\\s-nickname\\s-is\\s-registered.\\s-Please\\s-choose" - "NickServ" - "IDENTIFY" nil nil - ;; See also the 901 response code message. - "You\\s-are\\s-now\\s-identified\\s-for\\s-") - (GalaxyNet - "NS!nickserv@galaxynet.org" - "Please\\s-change\\s-nicks\\s-or\\s-authenticate." - "NS@services.galaxynet.org" - "AUTH" t nil nil) - (GRnet - "NickServ!service@irc.gr" - "This\\s-nickname\\s-is\\s-registered\\s-and\\s-protected." - "NickServ" - "IDENTIFY" nil nil - "Password\\s-accepted\\s--\\s-you\\s-are\\s-now\\s-recognized.") - (iip - "Trent@anon.iip" - "type\\s-/squery\\s-Trent\\s-identify\\s-" - "Trent@anon.iip" - "IDENTIFY" nil "SQUERY" nil) - (Libera.Chat - "NickServ!NickServ@services.libera.chat" - ;; Libera.Chat also accepts a password at login, see the `erc' - ;; :password argument. - "This\\s-nickname\\s-is\\s-registered.\\s-Please\\s-choose" - "NickServ" - "IDENTIFY" nil nil - ;; See also the 901 response code message. - "You\\s-are\\s-now\\s-identified\\s-for\\s-") - (OFTC - "NickServ!services@services.oftc.net" - ;; OFTC's NickServ doesn't ask you to identify anymore. - nil - "NickServ" - "IDENTIFY" nil nil - "You\\s-are\\s-successfully\\s-identified\\s-as\\s-\^B") - (Rizon - "NickServ!service@rizon.net" - "This\\s-nickname\\s-is\\s-registered\\s-and\\s-protected." - "NickServ" - "IDENTIFY" nil nil - "Password\\s-accepted\\s--\\s-you\\s-are\\s-now\\s-recognized.") - (QuakeNet - nil nil - "Q@CServe.quakenet.org" - "auth" t nil nil) - (SlashNET - "NickServ!services@services.slashnet.org" - "/msg\\s-NickServ\\s-IDENTIFY\\s-\^_password" - "NickServ@services.slashnet.org" - "IDENTIFY" nil nil nil)) - "Alist of NickServer details, sorted by network. -Every element in the list has the form - (NETWORK SENDER INSTRUCT-RX NICK SUBCMD YOUR-NICK-P ANSWER SUCCESS-RX) - -NETWORK is a network identifier, a symbol, as used in `erc-networks-alist'. -SENDER is the exact nick!user@host \"source\" for \"NOTICE\" messages -indicating success or requesting that the user identify. -INSTRUCT-RX is a regular expression matching a \"NOTICE\" from the - services bot instructing the user to identify. It must be non-null - when the option `erc-nickserv-identify-mode' is set to `autodetect'. - When it's `both', and this field is non-null, ERC will forgo - identifying on nick changes and after connecting. -NICK is the nickname of the services bot to use when issuing commands. -SUBCMD is the bot command for identifying, typically \"IDENTIFY\". -YOUR-NICK-P indicates whether to send the user's current nickname before - their password when identifying. -ANSWER is the command to use for the answer. The default is \"PRIVMSG\". -SUCCESS-RX is a regular expression matching the message NickServ sends - when you've successfully identified. -The last two elements are optional, as are others, where implied." - :type '(repeat - (list :tag "Nickserv data" - (symbol :tag "Network name") - (choice (string :tag "Nickserv's nick!user@host") - (const :tag "No message sent by Nickserv" nil)) - (choice (regexp :tag "Identify request sent by Nickserv") - (const :tag "No message sent by Nickserv" nil)) - (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)) - (choice :tag "Detect Success" - (regexp :tag "Pattern to match") - (const :tag "Do not try to detect success" nil))))) - - -(define-inline erc-nickserv-alist-sender (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 1 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-regexp (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 2 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-nickserv (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 3 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-ident-keyword (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 4 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-use-nick-p (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 5 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-ident-command (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 6 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -(define-inline erc-nickserv-alist-identified-regexp (network &optional entry) - (inline-letevals (network entry) - (inline-quote (nth 7 (or ,entry (assoc ,network erc-nickserv-alist)))))) - -;; Functions: - -(defcustom erc-nickserv-identified-hook nil - "Run this hook when NickServ acknowledged successful identification. -Hooks are called with arguments (NETWORK NICK)." - :type 'hook) - -(defun erc-nickserv-identification-autodetect (_proc parsed) - "Check for NickServ's successful identification notice. -Make sure it is the real NickServ for this network and that it has -specifically confirmed a successful identification attempt. -If this is the case, run `erc-nickserv-identified-hook'." - (let* ((network (erc-network)) - (sender (erc-nickserv-alist-sender network)) - (success-regex (erc-nickserv-alist-identified-regexp network)) - (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 told us we've successfully identified - (when (and sender (equal sspec sender) - success-regex - (string-match success-regex msg)) - (erc-log "NickServ IDENTIFY success notification detected") - (run-hook-with-args 'erc-nickserv-identified-hook network nick) - nil))) - -(defun erc-nickserv-identify-autodetect (_proc parsed) - "Identify to NickServ when an identify request is received. -Make sure it is the real NickServ for this network. -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) - (null erc-use-auth-source-for-nickserv-password)) - (let* ((network (erc-network)) - (sender (erc-nickserv-alist-sender network)) - (identify-regex (erc-nickserv-alist-regexp network)) - (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 sender (equal sspec sender) - identify-regex - (string-match identify-regex msg)) - (erc-log "NickServ IDENTIFY request detected") - (erc-nickserv-identify nil nick) - nil)))) - -(defun erc-nickserv-identify-on-connect (_server nick) - "Identify to Nickserv after the connection to the server is established." - (unless (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network))) - (erc-nickserv-identify nil nick))) - -(defun erc-nickserv-identify-on-nick-change (nick _old-nick) - "Identify to Nickserv whenever your nick changes." - (unless (and (eq erc-nickserv-identify-mode 'both) - (erc-nickserv-alist-regexp (erc-network))) - (erc-nickserv-identify nil nick))) - -(defun erc-nickserv-get-password (nick) - "Return the password for NICK from configured sources. -First, a password for NICK is looked up in -`erc-nickserv-passwords'. Then, it is looked up in auth-source -if `erc-use-auth-source-for-nickserv-password' is not nil. -Finally, interactively prompt the user, if -`erc-prompt-for-nickserv-password' is true. - -As soon as some source returns a password, the sequence of -lookups stops and this function returns it (or returns nil if it -is empty). Otherwise, no corresponding password was found, and -it returns nil." - (when-let* - ((nid (erc-networks--id-symbol erc-networks--id)) - (ret (or (when erc-nickserv-passwords - (assoc-default nick - (cadr (assq nid erc-nickserv-passwords)))) - (when (and erc-use-auth-source-for-nickserv-password - erc-auth-source-services-function) - (funcall erc-auth-source-services-function :user nick)) - (when erc-prompt-for-nickserv-password - (read-passwd - (format "NickServ password for %s on %s (RET to cancel): " - nick nid))))) - ((not (string-empty-p (erc--unfun ret))))) - ret)) - -(defvar erc-auto-discard-away) - -(defun erc-nickserv-send-identify (nick password) - "Send an \"identify \" message to NickServ. -Returns t if the message could be sent, nil otherwise." - (let* ((erc-auto-discard-away nil) - (network (erc-network)) - (nickserv-info (assoc network erc-nickserv-alist)) - (nickserv (or (erc-nickserv-alist-nickserv nil nickserv-info) - "NickServ")) - (identify-word (or (erc-nickserv-alist-ident-keyword - nil nickserv-info) - "IDENTIFY")) - (nick (if (erc-nickserv-alist-use-nick-p nil nickserv-info) - (concat nick " ") - "")) - (msgtype (or (erc-nickserv-alist-ident-command nil nickserv-info) - "PRIVMSG"))) - (erc-message msgtype - (concat nickserv " " identify-word " " nick - (erc--unfun password))))) - -(defun erc-nickserv-call-identify-function (nickname) - "Call `erc-nickserv-identify' with NICKNAME." - (declare (obsolete erc-nickserv-identify "28.1")) - (erc-nickserv-identify nil nickname)) - -;;;###autoload -(defun erc-nickserv-identify (&optional password nick) - "Identify to NickServ immediately. -Identification will either use NICK or the current nick if not -provided, and some password obtained through -`erc-nickserv-get-password' (which see). If no password can be -found, an error is reported through `erc-error'. - -Interactively, the user will be prompted for NICK, an empty -string meaning to default to the current nick. - -Returns t if the identify message could be sent, nil otherwise." - (interactive - (list - nil - (read-from-minibuffer "Nickname: " nil nil nil - 'erc-nick-history-list (erc-current-nick)))) - (unless (and nick (not (string= nick ""))) - (setq nick (erc-current-nick))) - (unless password - (setq password (erc-nickserv-get-password nick))) - (if password - (erc-nickserv-send-identify nick password) - (erc-error "Cannot find a password for nickname %s" - nick) - nil)) - - -;;;; Regaining nicknames - -(defcustom erc-services-regain-alist nil - "Alist mapping networks to nickname-regaining functions. -This option depends on the `services-regain' module being loaded. -Keys can also be symbols for user-provided \"context IDs\" (see -Info node `Network Identifier'). Functions run once, when first -establishing a logical IRC connection. Although ERC currently -calls them with one argument, the desired but rejected nickname, -robust user implementations should leave room for later additions -by defining an &rest _ parameter, as well. - -The simplest value is `erc-services-retry-nick-on-connect', which -attempts to kill off stale connections without engaging services -at all. Others, like `erc-services-issue-regain', and -`erc-services-issue-ghost-and-retry-nick', only speak a -particular flavor of NickServ. See their respective doc strings -for details and use cases." - :package-version '(ERC . "5.6") - :group 'erc-hooks - :type '(alist :key-type (symbol :tag "Network") - :value-type - (choice :tag "Strategy function" - (function-item erc-services-retry-nick-on-connect) - (function-item erc-services-issue-regain) - (function-item erc-services-issue-ghost-and-retry-nick) - function))) - -(defvar erc-services-regain-timeout-seconds 5 - "Seconds after which to run callbacks if necessary.") - -(defun erc-services-retry-nick-on-connect (want) - "Try at most once to grab nickname WANT after reconnecting. -Expect to be used when automatically reconnecting to servers -that are slow to abandon the previous connection. - -Note that this strategy may only work under certain conditions, -such as when a user's account name matches their nick." - (erc-cmd-NICK want)) - -(defun erc-services-issue-regain (want) - "Ask NickServ to regain nickname WANT. -Assume WANT belongs to the user and that the services suite -offers a \"REGAIN\" sub-command." - (erc-cmd-MSG (concat "NickServ REGAIN " want))) - -(defun erc-services-issue-ghost-and-retry-nick (want) - "Ask NickServ to \"GHOST\" nickname WANT. -After which, attempt to grab WANT before the contending party -reconnects. Assume the ERC user owns WANT and that the server's -services suite lacks a \"REGAIN\" command. - -Note that this function will only work for a specific services -implementation and is meant primarily as an example for adapting -as needed." - ;; While heuristics based on error text may seem brittle, consider - ;; the fact that \"is not online\" has been present in Atheme's - ;; \"GHOST\" responses since at least 2005. - (letrec ((attempts 3) - (on-notice - (lambda (_proc parsed) - (when-let ((nick (erc-extract-nick - (erc-response.sender parsed))) - ((erc-nick-equal-p nick "nickserv")) - (contents (erc-response.contents parsed)) - (case-fold-search t) - ((string-match (rx (or "ghost" "is not online")) - contents))) - (setq attempts 1) - (erc-server-send (concat "NICK " want) 'force)) - (when (zerop (cl-decf attempts)) - (remove-hook 'erc-server-NOTICE-functions on-notice t)) - nil))) - (add-hook 'erc-server-NOTICE-functions on-notice nil t) - (erc-message "PRIVMSG" (concat "NickServ GHOST " want)))) - -;;;###autoload(put 'services-regain 'erc--feature 'erc-services) -(define-erc-module services-regain nil - "Reacquire a nickname from your past self or some interloper. -This module only concerns itself with initial nick rejections -that occur during connection registration in response to an -opening \"NICK\" command. More specifically, the following -conditions must be met for ERC to activate this mechanism and -consider its main option, `erc-services-regain-alist': - - - the server must reject the opening \"NICK\" request - - ERC must request a temporary nickname - - the user must successfully authenticate - -In practical terms, this means that this module, which is still -somewhat experimental, is likely only useful in conjunction with -SASL authentication or CertFP rather than the traditional approach -provided by the `services' module it shares a library with (see Info -node `(erc) SASL' for more). - -This local module's minor mode is only active in server buffers." - ((when erc--target (erc-services-regain-mode -1))) nil localp) - -(cl-defmethod erc--nickname-in-use-make-request - ((want string) temp &context (erc-server-connected null) - (erc-services-regain-mode (eql t)) - (erc-services-regain-alist cons)) - "Schedule possible regain attempt upon establishing connection. -Expect WANT to be the desired nickname and TEMP to be the current -one." - (letrec - ((after-connect - (lambda (_ nick) - (remove-hook 'erc-after-connect after-connect t) - (when-let* - (((equal temp nick)) - (conn (or (erc-networks--id-given erc-networks--id) - (erc-network))) - (found (alist-get conn erc-services-regain-alist))) - (funcall found want)))) - (on-900 - (lambda (_ parsed) - (cancel-timer timer) - (remove-hook 'erc-server-900-functions on-900 t) - (unless (equal want (erc-current-nick)) - (if erc-server-connected - (funcall after-connect nil temp) - (when (or (eq parsed 'forcep) - (equal (car (erc-response.command-args parsed)) temp)) - (add-hook 'erc-after-connect after-connect nil t)))) - nil)) - (timer (run-at-time erc-services-regain-timeout-seconds - nil (lambda (buffer) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (funcall on-900 nil 'forcep)))) - (current-buffer)))) - (add-hook 'erc-server-900-functions on-900 nil t)) - (cl-call-next-method)) - -(provide 'erc-services) - - -;;; erc-services.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-sound.el b/lisp/erc/erc-sound.el deleted file mode 100644 index 0e8aa8d10be..00000000000 --- a/lisp/erc/erc-sound.el +++ /dev/null @@ -1,150 +0,0 @@ -;;; erc-sound.el --- CTCP SOUND support for ERC -*- lexical-binding: t -*- - -;; Copyright (C) 2002-2003, 2006-2025 Free Software Foundation, Inc. - -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcSound - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; Play sounds when users send you CTCP SOUND messages. - -;; This file also defines the command /sound so that you can send -;; sound requests to other users. - -;;; Usage: - -;; Add the following to your .emacs if you want to play sounds. -;; -;; (require 'erc-sound) -;; (erc-sound-enable) -;; -;; To send requests to other users from within query buffers, type the -;; following: -;; -;; /sound filename optional-message-text -;; -;; You can also type the following: -;; -;; /ctcp nickname sound filename optional-message - -;;; Code: - -(require 'erc) - -(defgroup erc-sound nil - "Make ERC play bells and whistles while chatting with people." - :group 'erc) - -;;;###autoload(put 'ctcp-sound 'erc--module 'sound) -;;;###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: - ((add-hook 'erc-ctcp-query-SOUND-hook #'erc-ctcp-query-SOUND) - (define-key erc-mode-map "\C-c\C-s" #'erc-toggle-sound)) - ;; Disable: - ((remove-hook 'erc-ctcp-query-SOUND-hook #'erc-ctcp-query-SOUND) - (define-key erc-mode-map "\C-c\C-s" #'undefined))) - -(defvar erc-message-english-CTCP-SOUND "%n (%u@%h) plays %s:%m" - "English template for a CTCP SOUND message.") - -(defcustom erc-play-sound t - "Play sounds when you receive CTCP SOUND requests." - :type 'boolean) - -(defcustom erc-sound-path nil - "List of directories that contain sound samples to play on SOUND events." - :type '(repeat directory)) - -(defcustom erc-default-sound nil - "Play this sound if the requested file was not found. -If this is set to nil or the file doesn't exist a beep will sound." - :type '(choice (const nil) - file)) - -(defvar erc-ctcp-query-SOUND-hook nil - "Hook to run after receiving a CTCP SOUND request.") - -(defun erc-cmd-SOUND (line &optional force) - "Send a CTCP SOUND message to the default target. -If `erc-play-sound' is non-nil, play the sound as well. - -/sound filename optional-message-text - -LINE is the text entered, including the command." - (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))) - -(defun erc-ctcp-query-SOUND (_proc nick login host _to msg) - "Display a CTCP SOUND message and play sound if `erc-play-sound' is non-nil." - (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) - "Play a sound file located in one of the directories in `erc-sound-path'. -See also `play-sound-file'." - (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)) - (play-sound-file filepath)) - (t (beep))) - (erc-log (format "Playing sound file %S" filepath)))) - -(defun erc-toggle-sound (&optional arg) - "Toggle 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) - -;;; erc-sound.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-speedbar.el b/lisp/erc/erc-speedbar.el deleted file mode 100644 index d8cbf11aeab..00000000000 --- a/lisp/erc/erc-speedbar.el +++ /dev/null @@ -1,685 +0,0 @@ -;;; erc-speedbar.el --- Speedbar support for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2001-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Contributor: Eric M. Ludlam -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcSpeedbar - -;; 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 3 of the License, 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. If not, see . - -;;; 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 -;; * Write tests that run in a term-mode subprocess -;; -;;; Code: - -(require 'erc) -(require 'erc-goodies) -(require 'erc-button) -(require 'speedbar) - -;;; Customization: - -(defgroup erc-speedbar nil - "Speedbar integration for ERC. -To open an ERC-flavored speedbar in a separate frame, run the -command `erc-speedbar-browser'. To use a window-based proxy -instead, run \\[erc-nickbar-mode] in a connected ERC buffer or -put `nickbar' in `erc-modules' before connecting. See Info -node `(speedbar) Top' for more about the underlying integration." - :group 'erc) - -(defcustom erc-speedbar-nicknames-window-width 18 - "Default width of the nicknames sidebar (in columns)." - :package-version '(ERC . "5.6") - :type 'integer) - -(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" - :type '(choice (const :tag "Sort users by channel activity" activity) - (const :tag "Sort users alphabetically" alphabetical) - (const :tag "Do not sort users" nil))) - -(defcustom erc-speedbar-hide-mode-topic 'headerline - "Hide mode and topic lines." - :package-version '(ERC . "5.6") - :type '(choice (const :tag "Always show" nil) - (const :tag "Always hide" t) - (const :tag "Omit when headerline visible" headerline))) - -(defcustom erc-speedbar-my-nick-face t - "A face to use for your nickname. -When the value is t, ERC uses `erc-current-nick-face' if -`erc-match' has been loaded and `erc-my-nick-face' otherwise. -When using the `nicks' module, you can see your nick as it -appears to others by coordinating with the option -`erc-nicks-skip-faces'." - :package-version '(ERC . "5.6") - :type '(choice face (const :tag "Current nick or own speaker face" t))) - -(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.") - -;;; 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) - (erc-install-speedbar-variables) - ;; 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 queryp queries-current-p) - (with-current-buffer buffer - ;; The function `dframe-help-echo' checks the default value of - ;; `dframe-help-echo-function' when deciding whether to visit - ;; the buffer and fire the callback. This works in normal - ;; speedbar frames because the event handler runs in the - ;; `window-buffer' of the active frame. But in our hacked - ;; version, where the frame is hidden, `speedbar-item-info' - ;; never runs without this workaround. - (setq-local dframe-help-echo-function #'ignore) - (setq serverp (erc--server-buffer-p)) - (setq chanp (erc-channel-p (erc-default-target))) - (setq queryp (erc-query-buffer-p) - queries-current-p (erc--queries-current-p))) - (defvar erc-nickbar-mode) - (cond ((and erc-nickbar-mode (null (get-buffer-window speedbar-buffer))) - (run-at-time 0 nil #'erc-nickbar-mode -1)) - (serverp - (erc-speedbar-channel-buttons nil 0 buffer)) - ((or chanp (and queryp queries-current-p)) - (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-search "+" 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 ??))) - (;; we have to contract this node - (string-search "-" 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-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 - (or (erc--target-channel-p erc--target) (erc--queries-current-p))) - (progn - (speedbar-make-tag-line - 'bracket ?+ 'erc-speedbar-expand-channel buffer - (erc--target-string (buffer-local-value 'erc--target buffer)) - 'erc-speedbar-goto-buffer buffer nil - depth) - (save-excursion - (forward-line -1) - (let ((table (buffer-local-value 'erc-channel-users buffer))) - (speedbar-add-indicator (format "(%d)" (hash-table-count table))) - (rx "(" (+ (any "0-9")) ")")))) - ;; Query target - (cl-assert (erc-query-buffer-p buffer)) - (speedbar-make-tag-line - 'bracket ?? nil nil - (buffer-name buffer) 'erc-speedbar-goto-buffer buffer nil - depth))) - -(defconst erc-speedbar--fmt-sentinel (gensym "erc-speedbar-") - "Symbol for identifying a nonstandard `speedbar-token' text property. -When encountered, ERC assumes the value's tail contains -`format'-compatible args.") - -(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-search "+" text) - (speedbar-change-expand-button-char ?-) - (speedbar-with-writable - (save-excursion - (end-of-line) (forward-char 1) - (let ((modes (buffer-local-value 'erc--mode-line-mode-string channel)) - (topic (erc-controls-interpret - (with-current-buffer channel erc-channel-topic)))) - (when modes - (speedbar-make-tag-line - 'angle ?m nil (list erc-speedbar--fmt-sentinel "Mode: %s" modes) - modes nil nil 'erc-notice-face (1+ indent))) - (unless (string= topic "") - (speedbar-make-tag-line - 'angle ?t nil (list erc-speedbar--fmt-sentinel "Topic: %s" topic) - topic nil nil 'erc-notice-face - (1+ indent))) - (unless (pcase erc-speedbar-hide-mode-topic - ('nil 'show) - ('headerline (null erc-header-line-format))) - (save-excursion - (goto-char (point-max)) - (forward-line (if (string= topic "") -1 -2)) - (put-text-property (pos-bol) (point-max) 'invisible t))) - (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) channel))))))))) - ((string-search "-" text) - (speedbar-change-expand-button-char ?+) - (speedbar-delete-subblock indent)) - (t (error "Ooops... not sure what to do"))) - (speedbar-center-buffer-smartly)) - -(defvar erc-speedbar--nick-face-function #'erc-speedbar--highlight-self-and-ops - "Function called when finding a face for fontifying nicks. -Called with the proposed nick, the `erc-server-user', and the -`erc-channel-user'. Should return any valid face, possibly -composed or anonymous, or nil.") - -(defun erc-speedbar--highlight-self-and-ops (buffer user cuser) - "Highlight own nick and op'd users in the speedbar." - (with-current-buffer buffer - (if (erc-current-nick-p (erc-server-user-nickname user)) - (pcase erc-speedbar-my-nick-face - ('t (if (facep 'erc-current-nick-face) - 'erc-current-nick-face - 'erc-my-nick-face)) - (v v)) - (or (and cuser (not (zerop (erc-channel-user-status cuser))) - erc-button-nickname-face) - 'erc-default-face)))) - -(defun erc-speedbar--on-click (nick sbtoken _indent) - ;; 0: finger, 1: name, 2: info, 3: buffer-name - (with-current-buffer (nth 3 sbtoken) - (erc-nick-popup (string-trim-left nick "[~&@%+]+")))) - -(defun erc-speedbar-insert-user (entry exp-char indent &optional buffer) - "Insert one user based on the channel member list ENTRY. -Expect EXP-CHAR to be the expansion character to use, INDENT the -current indentation level, and BUFFER the associated channel or -query buffer. Set the `speedbar-function' text property to -`erc-speedbar--on-click', which is called with the formatted -nick, a so-called \"token\", and the indent level. The token is -a list of four items: the userhost, the GECOS, the current -`erc-server-user' info slot, and the associated buffer." - (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)) - (nick-str (concat (with-current-buffer (or buffer (current-buffer)) - (erc-get-channel-membership-prefix cuser)) - nick)) - (finger (concat login (when (or login host) "@") host)) - (sbtoken (list finger name info (buffer-name buffer)))) - (if (or login host name info) ; we want to be expandable - (speedbar-make-tag-line - 'bracket ?+ 'erc-speedbar-expand-user sbtoken - nick-str #'erc-speedbar--on-click sbtoken - (funcall erc-speedbar--nick-face-function buffer user cuser) - 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-search "+" 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-search "-" 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))) - (dframe-select-attached-frame speedbar-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) (line-end-position)))) - -(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)) - ;; Print help if line has a non-standard ([-+?=]) button - ;; char and a `speedbar-token' property with a known CAR. - ((and-let* ((p (text-property-not-all (pos-bol) (pos-eol) - 'speedbar-token nil)) - (v (get-text-property p 'speedbar-token)) - ((eq erc-speedbar--fmt-sentinel (car v)))) - (apply #'message (cdr v)))) - (t - (message "%s" txt))))) - - -;;;; Status-sidebar integration - -(defvar erc-track-mode) -(defvar erc-track--switch-fallback-blockers) -(defvar erc-status-sidebar-buffer-name) -(declare-function erc-status-sidebar-set-window-preserve-size - "erc-status-sidebar" nil) - -(defvar erc-speedbar--buffer-options - '((speedbar-update-flag . t) - (speedbar-use-images . nil) - (speedbar-hide-button-brackets-flag . t))) - -(defvar erc-speedbar--hidden-speedbar-frame nil - "The original `speedbar-frame', which `erc-nickbar-mode' deletes. -It keeps a reference to it in order to run upstream teardown -procedures without having to create a dummy frame for that -purpose.") - -(defun erc-speedbar--emulate-sidebar-set-window-preserve-size () - (let ((erc-status-sidebar-buffer-name (buffer-name speedbar-buffer)) - (display-buffer-overriding-action - `(display-buffer-in-side-window - . ((side . right) - (window-width . ,erc-speedbar-nicknames-window-width))))) - (erc-status-sidebar-set-window-preserve-size))) - -(defun erc-speedbar--status-sidebar-mode--unhook () - "Remove hooks installed by `erc-status-sidebar-mode'." - (remove-hook 'window-configuration-change-hook - #'erc-speedbar--emulate-sidebar-set-window-preserve-size)) - -(defun erc-speedbar--emulate-sidebar () - "Perform local setup for `erc-nickbar-mode' in a new `speedbar-buffer'." - (require 'erc-status-sidebar) - (cl-assert speedbar-frame) - (cl-assert (eq speedbar-buffer (current-buffer))) - (cl-assert (eq speedbar-frame (selected-frame))) - (setq erc-speedbar--hidden-speedbar-frame speedbar-frame - ;; In Emacs 27, this is not `local-variable-if-set-p'. - dframe-controlled #'erc-speedbar--dframe-controlled) - (add-hook 'window-configuration-change-hook - #'erc-speedbar--emulate-sidebar-set-window-preserve-size nil t) - (add-hook 'kill-buffer-hook - #'erc-speedbar--status-sidebar-mode--unhook nil t) - (with-current-buffer speedbar-buffer - (pcase-dolist (`(,var . ,val) erc-speedbar--buffer-options) - (set (make-local-variable var) val))) - (when (memq 'nicks erc-modules) - (with-current-buffer speedbar-buffer - (add-function :around (local 'erc-speedbar--nick-face-function) - #'erc-speedbar--compose-nicks-face)))) - -(defun erc-speedbar--handle-delete-frame (event) - "Disable the nickbar if EVENT is deleting the proxy frame." - (when (and speedbar-frame - (cdr (frame-list)) - (pcase event - (`(delete-frame (,frame)) (eq frame speedbar-frame)))) - (erc-nickbar-mode -1))) - -(defun erc-speedbar--ensure (&optional forcep) - "Perform common setup for `erc-nickbar-mode'. -Without FORCEP, return early when the calling context isn't -associated with an ERC session." - (save-excursion - (when (or (erc-server-buffer) forcep) - (when erc-track-mode - (cl-pushnew '(derived-mode . speedbar-mode) - erc-track--switch-fallback-blockers :test #'equal)) - (unless speedbar-update-flag - (erc-button--display-error-notice-with-keys - (erc-server-buffer) - "Module `nickbar' needs `speedbar-update-flag' to be non-nil" - (and (not (display-graphic-p)) " in text terminals") - ". Setting to t for the current Emacs session." - " Customize it permanently to avoid this message.") - (setq speedbar-update-flag t)) - (when-let (((null speedbar-buffer)) - (speedbar-frame-parameters (backquote-list* - '(visibility . nil) - '(no-other-frame . t) - speedbar-frame-parameters)) - (speedbar-after-create-hook #'erc-speedbar--emulate-sidebar) - (original-frame (selected-frame))) - (erc-install-speedbar-variables) - ;; Run before toggling mode to prevent timer from being - ;; created twice. - (speedbar-change-initial-expansion-list "ERC") - (speedbar-frame-mode 1) - ;; The setup steps below can't go in the "create hook" because - ;; the frame with `window-main-window' will be raised and - ;; steal focus if you switch away from Emacs in the meantime. - (let ((frame speedbar-frame)) - (cl-assert (not (eq speedbar-frame original-frame))) - (select-frame (setq speedbar-frame original-frame)) - (delete-frame frame)) - ;; Allow deleting (our) `speedbar-frame' with the mouse. - (with-current-buffer speedbar-buffer - (kill-local-variable 'dframe-delete-frame-function) - (setq dframe-delete-frame-function - #'erc-speedbar--handle-delete-frame))) - (with-selected-frame speedbar-frame - (erc-speedbar--emulate-sidebar-set-window-preserve-size) - (erc-speedbar-toggle-nicknames-window-lock -1)) - (cl-assert (null (cdr (erc-speedbar--get-timers)))) - (with-current-buffer speedbar-buffer - (setq speedbar-update-flag t) - (speedbar-set-mode-line-format))))) - -(defvar erc-speedbar--force-update-interval-secs 5 - "Speedbar update period.") - -(defvar-local erc-speedbar--last-ran nil - "When non-nil, a Lisp timestamp updated when the speedbar timer runs.") - -(defun erc-speedbar--prod-dframe-timer (&rest _) - "Refresh speedbar if dormant for `erc-speedbar--force-update-interval-secs'." - (when (buffer-live-p speedbar-buffer) - (with-current-buffer speedbar-buffer - (when - (and dframe-timer - (or (null erc-speedbar--last-ran) - (time-less-p erc-speedbar--last-ran - (time-subtract - (current-time) - erc-speedbar--force-update-interval-secs)))) - (run-at-time 0 nil #'dframe-timer-fn)))) - nil) - -(defun erc-speedbar--reset-last-ran-on-timer () - "Reset `erc-speedbar--last-ran'." - (when speedbar-buffer - (with-current-buffer speedbar-buffer - (setq erc-speedbar--last-ran (current-time))))) - -;;;###autoload(autoload 'erc-nickbar-mode "erc-speedbar" nil t) -(define-erc-module nickbar nil - "Show nicknames for current target buffer in a side window. -When enabling, create a speedbar session if one doesn't exist and -show its buffer in an `erc-status-sidebar' window instead of a -separate frame. If ERC doesn't yet have any live connections, -defer activation until such time. This means the variable -`erc-nickbar-mode' may be t even though no actual speedbar yet -exists. When disabling, destroy the speedbar session. - -For controlling whether the speedbar window is selectable with -`other-window', see `erc-nickbar-toggle-nicknames-window-lock'." - ((add-hook 'erc--setup-buffer-hook #'erc-speedbar--ensure) - (add-hook 'speedbar-timer-hook #'erc-speedbar--reset-last-ran-on-timer) - (add-hook 'erc-insert-post-hook #'erc-speedbar--prod-dframe-timer) - (add-hook 'erc-server-PONG-functions #'erc-speedbar--prod-dframe-timer) - (erc-speedbar--ensure) - (unless (or erc--updating-modules-p - (and speedbar-buffer - (eq speedbar-frame - (window-frame (get-buffer-window speedbar-buffer t))))) - (when-let ((buf (or (and (derived-mode-p 'erc-mode) (current-buffer)) - (car (erc-buffer-filter #'erc--server-buffer-p))))) - (with-current-buffer buf - (erc-speedbar--ensure 'forcep))))) - ((remove-hook 'erc--setup-buffer-hook #'erc-speedbar--ensure) - (remove-hook 'speedbar-timer-hook #'erc-speedbar--reset-last-ran-on-timer) - (remove-hook 'erc-insert-post-hook #'erc-speedbar--prod-dframe-timer) - (remove-hook 'erc-server-PONG-functions #'erc-speedbar--prod-dframe-timer) - (when erc-track-mode - (setq erc-track--switch-fallback-blockers - (remove '(derived-mode . speedbar-mode) - erc-track--switch-fallback-blockers))) - ;; `speedbar-buffer' may be nil if the mode was never enabled, such - ;; as when disabling the module through Customize after startup. - (when speedbar-buffer - ;; Close associated windows and stop updating but leave timer. - (dolist (window (get-buffer-window-list speedbar-buffer nil t)) - (unless (frame-root-window-p window) - (when erc-speedbar--hidden-speedbar-frame - (cl-assert (not (eq (window-frame window) - erc-speedbar--hidden-speedbar-frame)))) - (delete-window window))) - (with-current-buffer speedbar-buffer - (setq speedbar-update-flag nil) - (speedbar-set-mode-line-format) - (unless (eq erc--module-toggle-prefix-arg most-negative-fixnum) - (dframe-close-frame)))))) - -(defun erc-speedbar--get-timers () - (cl-remove #'dframe-timer-fn timer-idle-list - :key #'timer--function - :test-not #'eq)) - -(defun erc-speedbar--dframe-controlled (arg) - (when speedbar-buffer - (cl-assert (eq speedbar-buffer (current-buffer)))) - (when (and erc-speedbar--hidden-speedbar-frame (numberp arg) (< arg 0)) - (when erc-nickbar-mode - (erc-nickbar-mode most-negative-fixnum)) - (setq speedbar-frame erc-speedbar--hidden-speedbar-frame - erc-speedbar--hidden-speedbar-frame nil) - (speedbar-frame-mode arg) ; -1 - ;; As of Emacs 29, `dframe-set-timer' can't remove `dframe-timer'. - (cl-assert (= 1 (length (erc-speedbar--get-timers))) t) - (cancel-function-timers #'dframe-timer-fn) - ;; `dframe-close-frame' kills the buffer but no function in - ;; erc-speedbar.el resets this to nil. - (setq erc-speedbar--hidden-speedbar-frame nil - speedbar-buffer nil - speedbar-frame nil))) - -(defun erc-speedbar-toggle-nicknames-window-lock (arg) - "Toggle whether nicknames window is selectable with \\[other-window]. -When ARG is a number, lock the window if non-negative. Otherwise, -unlock the window." - (interactive "P") - (unless erc-nickbar-mode - (user-error "`erc-nickbar-mode' inactive")) - (when-let ((window (get-buffer-window speedbar-buffer))) - (let ((val (cond ((natnump arg) t) - ((integerp arg) nil) - (t (not (erc-compat--window-no-other-p window)))))) - (with-current-buffer speedbar-buffer - (setq cursor-type (not val))) - (set-window-parameter window 'no-other-window val) - (unless (numberp arg) - (message "nick-window: %s" (if val "protected" "selectable")))))) - -(defalias 'erc-nickbar-toggle-nicknames-window-lock - #'erc-speedbar-toggle-nicknames-window-lock) - -;;;; Nicks integration - -(declare-function erc-nicks--highlight "erc-nicks" (nickname &optional face)) - -(defun erc-speedbar--compose-nicks-face (orig buffer user cuser) - (require 'erc-nicks) - (let ((rv (funcall orig buffer user cuser))) - (if-let ((nick (erc-server-user-nickname user)) - (face (with-current-buffer buffer - (erc-nicks--highlight nick rv))) - ((not (eq face erc-button-nickname-face)))) - (cons face (ensure-list rv)) - rv))) - - -(provide 'erc-speedbar) -;;; erc-speedbar.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-spelling.el b/lisp/erc/erc-spelling.el deleted file mode 100644 index b354349bcec..00000000000 --- a/lisp/erc/erc-spelling.el +++ /dev/null @@ -1,143 +0,0 @@ -;;; erc-spelling.el --- use flyspell in ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2005-2025 Free Software Foundation, Inc. - -;; Author: Jorgen Schaefer -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, irc -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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) - -(defgroup erc-spelling nil - "Flyspell integration for ERC." - :group 'erc) - -;;;###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) - (unless erc--updating-modules-p - (erc-with-all-buffers-of-server nil nil - (erc-spelling-init (current-buffer))))) - ((remove-hook 'erc-connect-pre-hook #'erc-spelling-init) - (dolist (buffer (erc-buffer-list)) - (remove-hook 'flyspell-incorrect-hook #'erc-spelling--flyspell-check t) - (with-current-buffer buffer (flyspell-mode 0))))) - -(defcustom erc-spelling-dictionaries nil - "An alist mapping buffer names to dictionaries. - -Each element is a list of the form (KEY VALUE), where KEY is a buffer -name and VALUE a locale or dictionary name known to `ispell', for -example: ((\"Libera.Chat\" \"en_US\") (\"#esperanto\" \"esperanto\")). - -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 (list (string :tag "Buffer name") - (string :tag "Dictionary"))))) - -(defun erc-spelling-init (buffer) - "Enable flyspell mode in an ERC buffer. -The current buffer is given by BUFFER." - (with-current-buffer buffer - (let ((name (downcase (buffer-name))) - (dicts erc-spelling-dictionaries)) - (when dicts - (while (and dicts - (not (string= name (downcase (caar dicts))))) - (setq dicts (cdr dicts))) - (setq ispell-local-dictionary - (if dicts - (cadr (car dicts)) - (erc-with-server-buffer ispell-local-dictionary))))) - (add-hook 'flyspell-incorrect-hook #'erc-spelling--flyspell-check 20 t) - (flyspell-mode 1))) - -(defun erc-spelling-unhighlight-word (word) - "Unhighlight the given WORD. -The cadr is the beginning and the caddr is the end." - (let ((beg (nth 1 word)) - (end (nth 2 word))) - (flyspell-unhighlight-at beg) - (when (> end beg) - (flyspell-unhighlight-at (1- end))))) - -(defun erc-spelling-flyspell-verify () - "Flyspell only the input line, nothing else." - (declare (obsolete erc-spelling--flyspell-input-p "31.1")) - ;; FIXME: Don't use `flyspell-word'! - (let ((word-data (and (boundp 'flyspell-word) - flyspell-word))) - (when word-data - (cond ((< (point) erc-input-marker) - nil) - ;; don't spell-check names of users - ((and erc-channel-users - (erc-get-channel-user (car word-data))) - (erc-spelling-unhighlight-word word-data) - nil) - ;; if '/' occurs before the word, don't spell-check it - ((eq (char-before (nth 1 word-data)) ?/) - (erc-spelling-unhighlight-word word-data) - nil) - (t t))))) - -;; Do this down here to avoid having to wrap the call sites above in -;; `with-suppressed-warnings'. -(make-obsolete 'erc-spelling-unhighlight-word - "value from `flyspell-get-word' now unused" "31.1") - -(defun erc-spelling--flyspell-check (beg end _) - "Return non-nil and remove overlay if text between BEG and END is correct." - (or (and erc-channel-users - (erc-get-channel-user (buffer-substring-no-properties beg end)) - (always (flyspell-unhighlight-at beg))) - (and erc-input-marker (> beg erc-input-marker) (eq (char-before beg) ?/) - (or (= beg (1+ erc-input-marker)) ; allow /misspelled at prompt - (erc-command-symbol (buffer-substring-no-properties beg end))) - (always (flyspell-unhighlight-at beg))))) - -(defun erc-spelling--flyspell-input-p () - "Return non-nil if Flyspell should check the prompt input at point." - (>= (point) erc-input-marker)) - -(put 'erc-mode - 'flyspell-mode-predicate - #'erc-spelling--flyspell-input-p) - -(provide 'erc-spelling) - -;;; erc-spelling.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el deleted file mode 100644 index 3aee51666d5..00000000000 --- a/lisp/erc/erc-stamp.el +++ /dev/null @@ -1,1187 +0,0 @@ -;;; erc-stamp.el --- Timestamping for ERC messages -*- lexical-binding:t -*- - -;; Copyright (C) 2002-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm, timestamp -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; 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) - -(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 init 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." - :type '(choice (const nil) - (string))) - -(defcustom erc-timestamp-format-left "\n[%a %b %e %Y]\n" - "Format recognized by `format-time-string' for date stamps. -Only considered when `erc-insert-timestamp-function' is set to -`erc-insert-timestamp-left-and-right'. Used for displaying date -stamps on their own line, between messages. ERC inserts this -flavor of stamp as a separate \"pseudo message\", so a final -newline isn't necessary. For compatibility, only additional -trailing newlines beyond the first become empty lines. For -example, the default value results in an empty line after the -previous message, followed by the timestamp on its own line, -followed immediately by the next message on the next line. ERC -expects to display these stamps less frequently, so the -formatting specifiers should reflect that. To omit these stamps -entirely, use a different `erc-insert-timestamp-function', such -as `erc-timestamp-format-right'. Note that changing this value -during an ERC session requires cycling `erc-stamp-mode'." - :type 'string) - -(defcustom erc-timestamp-format-right nil - "If set to a string, messages will be timestamped. -This string is processed using `format-time-string'. -Good examples are \"%T\" and \"%H:%M\". - -This timestamp is used for timestamps on the right side of the -screen when `erc-insert-timestamp-function' is set to -`erc-insert-timestamp-left-and-right'. - -Unlike `erc-timestamp-format' and `erc-timestamp-format-left', if -the value of this option is nil, it falls back to using the value -of `erc-timestamp-format'." - :package-version '(ERC . "5.6") - :type '(choice (const nil) - (string))) -(make-obsolete-variable 'erc-timestamp-format-right - 'erc-timestamp-format "30.1") - -(defcustom erc-insert-timestamp-function 'erc-insert-timestamp-left-and-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. - -You will probably want to set -`erc-insert-away-timestamp-function' to the same value." - :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right) - (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." - :type '(choice (const nil) - (string))) - -(defcustom erc-insert-away-timestamp-function - #'erc-insert-timestamp-left-and-right - "Function to use to insert the away timestamp. - -See `erc-insert-timestamp-function' for details." - :type '(choice (const :tag "Both sides" erc-insert-timestamp-left-and-right) - (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." - :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. When attempting to enable this option -after `erc-stamp-mode' is already active, you may need to run the -command `erc-show-timestamps' (or `erc-hide-timestamps') in the -appropriate ERC buffer before the change will take effect." - :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." - :type '(choice (const :tag "Timestamped Monday, 15:04:05" - "Timestamped %A, %H:%M:%S") - (const :tag "2006-01-02 15:04:05 MST" "%F %T %Z") - string)) - -(defcustom erc-echo-timestamp-zone nil - "Default timezone for the option `erc-echo-timestamps'. -Also affects the command `erc-echo-timestamp' (singular). See -the ZONE parameter of `format-time-string' for a description of -acceptable value types." - :type '(choice boolean number (const wall) (list number string)) - :package-version '(ERC . "5.6")) - -(defcustom erc-timestamp-intangible nil - "Whether the timestamps should be intangible, i.e. prevent the point -from entering them and instead jump over them." - :version "24.5" - :type 'boolean) - -(defface erc-timestamp-face '((t :weight bold :foreground "green")) - "ERC timestamp face." - :group 'erc-faces) - -;; New libraries should only autoload the minor mode for a module's -;; preferred name (rather than its alias). - -;;;###autoload(put 'timestamp 'erc--module 'stamp) -;;;###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-stamp--setup) - (add-hook 'erc-insert-modify-hook #'erc-add-timestamp 70) - (add-hook 'erc-send-modify-hook #'erc-add-timestamp 70) - (add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect) - (unless erc--updating-modules-p (erc-buffer-do #'erc-stamp--setup))) - ((remove-hook 'erc-mode-hook #'erc-stamp--setup) - (remove-hook 'erc-insert-modify-hook #'erc-add-timestamp) - (remove-hook 'erc-send-modify-hook #'erc-add-timestamp) - (remove-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect) - (erc-buffer-do #'erc-stamp--setup))) - -(defvar erc-stamp--invisible-property nil - "Existing `invisible' property value and/or symbol `timestamp'.") - -(defvar erc-stamp--skip-when-invisible nil - "Escape hatch for omitting stamps when first char is invisible.") - -(defun erc-stamp--recover-on-reconnect () - "Attempt to restore \"last-inserted\" snapshots from prior session." - (when-let ((priors (or erc--server-reconnecting erc--target-priors))) - (dolist (var '(erc-timestamp-last-inserted - erc-timestamp-last-inserted-left - erc-timestamp-last-inserted-right - erc-stamp--deferred-date-stamp - erc-stamp--date-stamps)) - (when-let (existing (alist-get var priors)) - (set var existing))))) - -(defvar erc-stamp--current-time nil - "The current time when calling `erc-insert-timestamp-function'. -Specifically, this is the same Lisp time object used to create -the stamp passed to `erc-insert-timestamp-function'.") - -(cl-defgeneric erc-stamp--current-time () - "Return a Lisp time object to associate with an IRC message. -This becomes the message's `erc--ts' text property." - (erc-compat--current-lisp-time)) - -(cl-defmethod erc-stamp--current-time :around () - (or erc-stamp--current-time (cl-call-next-method))) - -(defvar erc-stamp--allow-unmanaged-p nil - "Non-nil means run `erc-add-timestamp' almost unconditionally. -This is an unofficial escape hatch for code wanting to use -lower-level message-insertion functions, like `erc-insert-line', -directly. Third parties needing such functionality should -petition for it via \\[erc-bug].") - -(defvar erc-stamp--permanent-cursor-sensor-functions nil - "Non-nil means add `cursor-sensor-functions' unconditionally. -This is an unofficial escape hatch for code wanting the text -property `cursor-sensor-functions' to always be present, -regardless of the option `erc-echo-timestamps'. Third parties -needing such pre-5.6 behavior to stick around should make that -known via \\[erc-bug].") - -(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 (and (not erc-stamp--allow-unmanaged-p) - (or (null erc--msg-props) - (erc--memq-msg-prop 'erc--skip 'stamp))) - (let* ((ct (or (erc--check-msg-prop 'erc--ts) - (erc-stamp--current-time))) - (invisible (get-text-property (point-min) 'invisible)) - (erc-stamp--invisible-property - ;; FIXME on major version bump, make this `erc-' prefixed. - (if invisible `(timestamp ,@(ensure-list invisible)) 'timestamp)) - (skipp (or (and erc-stamp--skip-when-invisible invisible) - (erc--check-msg-prop 'erc--ephemeral))) - (erc-stamp--current-time ct)) - (when erc--msg-props - (puthash 'erc--ts ct erc--msg-props)) - (unless skipp - (funcall erc-insert-timestamp-function - (erc-format-timestamp ct erc-timestamp-format))) - ;; Check `erc-insert-away-timestamp-function' for historical - ;; reasons even though its Custom :type only allows functions. - (when (and (not (or skipp erc-timestamp-format)) - erc-away-timestamp-format - (functionp erc-insert-away-timestamp-function) - (erc-away-time)) - (funcall erc-insert-away-timestamp-function - (erc-format-timestamp ct erc-away-timestamp-format))) - (when erc-stamp--permanent-cursor-sensor-functions - (add-text-properties (point-min) (max (point-min) (1- (point-max))) - ;; It's important for the function to - ;; be different on different entries (bug#22700). - (list 'cursor-sensor-functions - ;; Regions are no longer contiguous ^ - '(erc--echo-ts-csf) 'erc--ts ct)))))) - -(defvar-local erc-timestamp-last-window-width nil - "The width of the last window that showed the current buffer. -his is used by `erc-insert-timestamp-right' when the current -buffer is not shown in any window.") - -(defvar-local erc-timestamp-last-inserted nil - "Last timestamp inserted into the buffer.") - -(defvar-local erc-timestamp-last-inserted-left nil - "Last \"date stamp\" inserted into the left side of the buffer. -Used when `erc-insert-timestamp-function' is set to -`erc-timestamp-left-and-right'. If the format string specified -by `erc-timestamp-format-left' includes trailing newlines, this -value omits the last one.") - -(defvar-local erc-timestamp-last-inserted-right nil - "Last timestamp inserted into the right side of the buffer. -This is used when `erc-insert-timestamp-function' is set to -`erc-timestamp-left-and-right'") - -(defcustom erc-timestamp-only-if-changed-flag t - "Non-nil means 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." - :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." - :type '(choice - (integer :tag "Column number") - (const :tag "Unspecified" nil))) - -(defcustom erc-timestamp-use-align-to (and (display-graphic-p) t) - "If non-nil, use the :align-to display property to align the stamp. -This gives better results when variable-width characters (like -Asian language characters and math symbols) precede a timestamp. - -This option only matters when `erc-insert-timestamp-function' is -set to `erc-insert-timestamp-right' or that option's default, -`erc-insert-timestamp-left-and-right'. If the value is a -positive integer, alignment occurs that many columns from the -right edge. - -Enabling this option produces a side effect in that stamps aren't -indented in saved logs. When its value is an integer, this -option adds a space after the end of a message if the stamp -doesn't already start with one. And when its value is t, it adds -a single space, unconditionally." - :type '(choice boolean integer) - :package-version '(ERC . "5.6")) - -(defvar-local erc-stamp--margin-width nil - "Width in columns of margin for `erc-stamp--display-margin-mode'. -Only consulted when resetting or initializing margin.") - -(defvar-local erc-stamp--margin-left-p nil - "Whether `erc-stamp--display-margin-mode' uses the left margin. -During initialization, the mode respects this variable's existing -value if it already has a local binding. Otherwise, modules can -bind this to any value while enabling the mode. If it's nil, ERC -will check to see if `erc-insert-timestamp-function' is -`erc-insert-timestamp-left', interpreting the latter as a non-nil -value. It'll then coerce any non-nil value to t.") - -(defun erc-stamp--init-margins-on-connect (&rest _) - (let ((existing (if erc-stamp--margin-left-p - left-margin-width - right-margin-width))) - (erc-stamp--adjust-margin existing 'resetp))) - -(defun erc-stamp--adjust-margin (cols &optional resetp) - "Adjust managed margin by increment COLS. -With RESETP, set margin's width to COLS. However, if COLS is -zero, set the width to a non-nil `erc-stamp--margin-width'. -Otherwise, go with the `string-width' of `erc-timestamp-format'. -However, when `erc-stamp--margin-left-p' is non-nil and the -prompt is wider, use its width instead." - (let* ((leftp erc-stamp--margin-left-p) - (width - (if resetp - (or (and (not (zerop cols)) cols) - erc-stamp--margin-width - (max (if leftp - (cond ((fboundp 'erc-fill--wrap-measure) - (let* ((b erc-insert-marker) - (e (1- erc-input-marker)) - (w (erc-fill--wrap-measure b e))) - (/ (if (consp w) (car w) w) - (frame-char-width)))) - ((fboundp 'string-pixel-width) - (/ (string-pixel-width (erc-prompt)) - (frame-char-width))) - (t (string-width (erc-prompt)))) - 0) - (1+ (string-width - (or (if leftp - erc-timestamp-last-inserted - erc-timestamp-last-inserted-right) - (erc-format-timestamp - (current-time) erc-timestamp-format)))))) - (+ (if leftp left-margin-width right-margin-width) cols)))) - (set (if leftp 'left-margin-width 'right-margin-width) width) - (when (eq (current-buffer) (window-buffer)) - (set-window-margins nil - (if leftp width left-margin-width) - (if leftp right-margin-width width))))) - -;;;###autoload -(defun erc-stamp-prefix-log-filter (text) - "Prefix every message in the buffer with a stamp. -Remove trailing stamps as well. For now, hard code the format to -\"ZNC\"-log style, which is [HH:MM:SS]. Expect to be used as a -`erc-log-filter-function' when `erc-timestamp-use-align-to' is -non-nil." - (insert text) - (goto-char (point-min)) - (while - (progn - (when-let (((< (point) (pos-eol))) - (end (1- (pos-eol))) - ((eq 'erc-timestamp (field-at-pos end))) - (beg (field-beginning end)) - ;; Skip a line that's just a timestamp. - ((> beg (point)))) - (delete-region beg (1+ end))) - (when-let (time (erc--get-inserted-msg-prop 'erc--ts)) - (insert (format-time-string "[%H:%M:%S] " time))) - (zerop (forward-line)))) - "") - -;; These are currently extended manually, but we could also bind -;; `text-property-default-nonsticky' and call `insert-and-inherit' -;; instead of `insert', but we'd have to pair the props with differing -;; boolean values for left and right stamps. Also, since this hook -;; runs last, we can't expect overriding sticky props to be absent, -;; even though, as of 5.6, `front-sticky' is only added by the -;; `readonly' module after hooks run. -(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix) - "Extant properties at the start of a message inherited by the stamp.") - -(defvar-local erc-stamp--skip-left-margin-prompt-p nil - "Don't display prompt in left margin.") - -(declare-function erc--remove-text-properties "erc" (string)) - -;; Currently, `erc-insert-timestamp-right' hard codes its display -;; property to use `right-margin', and `erc-insert-timestamp-left' -;; does the same for `left-margin'. However, there's no reason a -;; trailing stamp couldn't be displayed on the left and vice versa. -(define-minor-mode erc-stamp--display-margin-mode - "Internal minor mode for built-in modules integrating with `stamp'. -Arranges for displaying stamps in a single margin, with the -variable `erc-stamp--margin-left-p' controlling which one. -Provides `erc-stamp--margin-width' and `erc-stamp--adjust-margin' -to help manage the chosen margin's width. Also removes `display' -properties in killed text to reveal stamps. The invoking module -should set controlling variables, like `erc-stamp--margin-width' -and `erc-stamp--margin-left-p', before activating the mode." - :interactive nil - (if erc-stamp--display-margin-mode - (progn - (setq fringes-outside-margins t) - (when (eq (current-buffer) (window-buffer)) - (set-window-buffer (selected-window) (current-buffer))) - (setq erc-stamp--margin-left-p (and erc-stamp--margin-left-p t)) - (if (or erc-server-connected (not (functionp erc-prompt))) - (erc-stamp--init-margins-on-connect) - (add-hook 'erc-after-connect - #'erc-stamp--init-margins-on-connect nil t)) - (add-function :filter-return (local 'filter-buffer-substring-function) - #'erc--remove-text-properties) - (add-hook 'erc--setup-buffer-hook - #'erc-stamp--refresh-left-margin-prompt nil t) - (when (and erc-stamp--margin-left-p - (not erc-stamp--skip-left-margin-prompt-p)) - (add-hook 'erc--refresh-prompt-hook - #'erc-stamp--display-prompt-in-left-margin nil t))) - (remove-function (local 'filter-buffer-substring-function) - #'erc--remove-text-properties) - (remove-hook 'erc-after-connect - #'erc-stamp--init-margins-on-connect t) - (remove-hook 'erc--refresh-prompt-hook - #'erc-stamp--display-prompt-in-left-margin t) - (remove-hook 'erc--setup-buffer-hook - #'erc-stamp--refresh-left-margin-prompt t) - (kill-local-variable (if erc-stamp--margin-left-p - 'left-margin-width - 'right-margin-width)) - (kill-local-variable 'erc-stamp--skip-left-margin-prompt-p) - (kill-local-variable 'fringes-outside-margins) - (kill-local-variable 'erc-stamp--margin-left-p) - (kill-local-variable 'erc-stamp--margin-width) - (when (eq (current-buffer) (window-buffer)) - (set-window-margins nil left-margin-width nil) - (set-window-buffer (selected-window) (current-buffer))))) - -(defvar-local erc-stamp--last-prompt nil) - -(defun erc-stamp--display-prompt-in-left-margin () - "Show prompt in the left margin with padding." - (when (or (not erc-stamp--last-prompt) (functionp erc-prompt) - (> (string-width erc-stamp--last-prompt) left-margin-width)) - (let ((s (buffer-substring erc-insert-marker (1- erc-input-marker)))) - ;; Prevent #("abc" n m (display ((...) #("abc" p q (display...)))) - (remove-text-properties 0 (length s) '(display nil) s) - (when (and erc-stamp--last-prompt - (>= (string-width erc-stamp--last-prompt) left-margin-width)) - (let ((sm (truncate-string-to-width s (1- left-margin-width) 0 nil t))) - ;; This papers over a subtle off-by-1 bug here. - (unless (equal sm s) - (setq s (concat sm (substring s -1)))))) - (setq erc-stamp--last-prompt (string-pad s left-margin-width nil t)))) - (put-text-property erc-insert-marker (1- erc-input-marker) - 'display `((margin left-margin) ,erc-stamp--last-prompt)) - erc-stamp--last-prompt) - -(defun erc-stamp--refresh-left-margin-prompt () - "Forcefully-recompute display property of prompt in left margin." - (with-silent-modifications - (unless (functionp erc-prompt) - (setq erc-stamp--last-prompt nil)) - (erc--refresh-prompt))) - -(cl-defmethod erc--conceal-prompt - (&context (erc-stamp--display-margin-mode (eql t)) - (erc-stamp--margin-left-p (eql t)) - (erc-stamp--skip-left-margin-prompt-p null)) - (when-let (((null erc--hidden-prompt-overlay)) - (prompt (string-pad erc-prompt-hidden left-margin-width nil 'start)) - (ov (make-overlay erc-insert-marker (1- erc-input-marker) - nil 'front-advance))) - (overlay-put ov 'display `((margin left-margin) ,prompt)) - (setq erc--hidden-prompt-overlay ov))) - -(defun erc-insert-timestamp-left (string) - "Insert timestamps at the beginning of the line." - (erc--insert-timestamp-left string)) - -(cl-defmethod erc--insert-timestamp-left (string) - (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) - (erc-put-text-property 0 len 'invisible erc-stamp--invisible-property s) - (insert s))) - -(cl-defmethod erc--insert-timestamp-left - (string &context (erc-stamp--display-margin-mode (eql t))) - (unless (and erc-timestamp-only-if-changed-flag - (string-equal string erc-timestamp-last-inserted)) - (goto-char (point-min)) - (insert-and-inherit (setq erc-timestamp-last-inserted string)) - (dolist (p erc-stamp--inherited-props) - (when-let ((v (get-text-property (point) p))) - (put-text-property (point-min) (point) p v))) - (erc-put-text-property (point-min) (point) 'invisible - erc-stamp--invisible-property) - (put-text-property (point-min) (point) 'field 'erc-timestamp) - (put-text-property (point-min) (point) - 'display `((margin left-margin) ,string)))) - -(defun erc-insert-aligned (string pos) - "Insert STRING at the POSth column. - -If `erc-timestamp-use-align-to' is t, use the :align-to display -property to get to the POSth column." - (declare (obsolete "inlined and removed from client code path" "30.1")) - (if (not erc-timestamp-use-align-to) - (indent-to pos) - (insert " ") - (put-text-property (1- (point)) (point) 'display - (list 'space ':align-to pos))) - (insert string)) - -;; Silence byte-compiler -(defvar erc-fill-column) - -(defvar erc-stamp--omit-properties-on-folded-lines nil - "Skip properties before right stamps occupying their own line. -This escape hatch restores pre-5.6 behavior that left leading -white space alone (unpropertized) for right-sided stamps folded -onto their own line.") - -(defun erc-insert-timestamp-right (string) - "Insert timestamp on the right side of the screen. -STRING is the timestamp to insert. This 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 as the -right boundary. In case multiple windows show the buffer, the -width of the most recently selected one is used. If the buffer -is not shown, the timestamp will be printed just before the -window width of the last window that showed it. If the buffer -was never shown, and `fill-column' is set, it will be printed -just before `fill-column'. As a last resort, timestamp will be -printed just after each line's text (no alignment)." - (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* ((str-width (string-width string)) - (buffer-invisibility-spec nil) ; `current-column' > 0 - window ; used in computation of `pos' only - (pos (cond - (erc-timestamp-right-column erc-timestamp-right-column) - ((and (boundp 'erc-fill-mode) - erc-fill-mode - (boundp 'erc-fill-column) - erc-fill-column) - (1+ (- erc-fill-column str-width))) - ((setq window (get-buffer-window nil t)) - (setq erc-timestamp-last-window-width - (window-width window)) - (- erc-timestamp-last-window-width str-width)) - (erc-timestamp-last-window-width - (- erc-timestamp-last-window-width str-width)) - (fill-column - (1+ (- fill-column str-width))) - (t (current-column)))) - (from (point)) - (col (current-column))) - ;; The following is a kludge used to calculate whether to move - ;; to the next line before inserting a stamp. It allows for - ;; some margin of error if what is displayed on the line differs - ;; from the number of characters on the line. - (setq col (+ col (ceiling (/ (- col (- (point) (line-beginning-position))) 1.6)))) - ;; For compatibility reasons, the `erc-timestamp' field includes - ;; intervening white space unless a hard break is warranted. - (pcase erc-timestamp-use-align-to - ((guard erc-stamp--display-margin-mode) - (let ((s (propertize (substring-no-properties string) - 'invisible erc-stamp--invisible-property))) - (insert " ") - (put-text-property 0 (length string) 'display - `((margin right-margin) ,s) - string))) - ((and 't (guard (< col pos))) - (insert " ") - (put-text-property from (point) 'display `(space :align-to ,pos))) - ((pred integerp) ; (cl-type (integer 0 *)) - (insert " ") - (when (eq ?\s (aref string 0)) - (setq string (substring string 1))) - (let ((s (+ erc-timestamp-use-align-to (string-width string)))) - (put-text-property from (point) 'display - `(space :align-to (- right ,s))))) - ((guard (>= col pos)) (newline) (indent-to pos) - (when erc-stamp--omit-properties-on-folded-lines (setq from (point)))) - (_ (indent-to pos))) - (insert string) - (dolist (p erc-stamp--inherited-props) - (when-let ((v (get-text-property (1- from) p))) - (put-text-property from (point) p v))) - (erc-put-text-property from (point) 'field 'erc-timestamp) - (erc-put-text-property from (point) 'rear-nonsticky t) - (erc-put-text-property from (point) 'invisible - erc-stamp--invisible-property) - (when erc-timestamp-intangible - (erc-put-text-property from (1+ (point)) 'cursor-intangible t))))) - -(defvar erc-stamp--insert-date-hook nil - "Hook run when inserting a date stamp.") - -(defvar-local erc-stamp--date-format-end nil - "Tristate value indicating how and whether date stamps have been set up. -A non-nil value means the buffer has been initialized to use date -stamps. An integer marks the `substring' TO parameter for -truncating `erc-timestamp-format-left' prior to rendering. A -value of t means the option's value doesn't require trimming.") - -;; This struct and its namesake variable exist to assist in testing. -(cl-defstruct erc-stamp--date - "Data relevant to life cycle of date-stamp insertion." - ( ts (error "Missing `ts' field") :type (or cons integer) - :documentation "Time recorded by `erc-insert-timestamp-left-and-right'.") - ( str (error "Missing `str' field") :type string - :documentation "Stamp rendered by `erc-insert-timestamp-left-and-right'.") - ( fn #'ignore :type (or null function) - ;; Use `ignore' as a third state to mean the creation of a bespoke - ;; date-insertion function has been requested but not completed. - :documentation "Deferred insertion function created by post-modify hook.") - ( marker (make-marker) :type marker - :documentation "Insertion marker.")) - -(defvar-local erc-stamp--deferred-date-stamp nil - "Active `erc-stamp--date' instance. -Non-nil between insertion-modification and \"done\" (or timer) hook.") - -(defvar-local erc-stamp--date-stamps nil - "List of stamps in the current buffer.") - -(defun erc-stamp--propertize-left-date-stamp (&rest _) - (add-text-properties (point-min) (1- (point-max)) '(field erc-timestamp)) - (run-hooks 'erc-stamp--insert-date-hook)) - -(defun erc-stamp--format-date-stamp (ct) - "Format left date stamp with `erc-timestamp-format-left'." - (unless erc-stamp--date-format-end - ;; Don't add text properties to the trailing newline. - (setq erc-stamp--date-format-end - (if (string-suffix-p "\n" erc-timestamp-format-left) -1 t))) - ;; Ignore existing `invisible' prop value because date stamps should - ;; never be hideable except via `timestamp'. - (let (erc-stamp--invisible-property) - (erc-format-timestamp ct (if (numberp erc-stamp--date-format-end) - (substring erc-timestamp-format-left - 0 erc-stamp--date-format-end) - erc-timestamp-format-left)))) - -(defun erc-stamp--find-insertion-point (p target-time) - "Scan buffer backwards from P looking for TARGET-TIME. -Return P or, if found, a position less than P." - ;; Continue searching after encountering a message without a - ;; timestamp because date stamps must be unique, and - ;; "Re-establishing connection" messages should have stamps. - (while-let ((pp (max (1- p) (point-min))) - (q (previous-single-property-change pp 'erc--ts)) - (qq (erc--get-inserted-msg-beg q)) - (ts (get-text-property qq 'erc--ts)) - ((not (time-less-p ts target-time)))) - (setq p qq)) - p) - -(defun erc-stamp-inserting-date-stamp-p () - "Return non-nil if the narrowed buffer contains a date stamp. -Expect to be called by members of `erc-insert-modify-hook' and -`erc-insert-post-hook' to detect whether the message being -inserted is a date stamp." - (erc--check-msg-prop 'erc--msg 'datestamp)) - -(defun erc-stamp--defer-date-insertion-on-post-modify (hook-var) - "Schedule a date stamp to be inserted via HOOK-VAR. -Do so when `erc-stamp--deferred-date-stamp' and its `fn' slot are -non-nil." - (when-let ((data erc-stamp--deferred-date-stamp) - ((eq (erc-stamp--date-fn data) #'ignore)) - (ct (erc-stamp--date-ts data)) - (rendered (erc-stamp--date-str data)) - (buffer (current-buffer)) - (symbol (make-symbol "erc-stamp--insert-date")) - (marker (setf (erc-stamp--date-marker data) (point-min-marker)))) - (setf (erc-stamp--date-fn data) symbol) - ;; Disable logging in case `erc-log-write-after-insert' is in effect. - (when erc--msg-props - (push 'log (gethash 'erc--skip erc--msg-props))) - (fset symbol - (lambda (&rest _) - (remove-hook hook-var symbol) - (setf (erc-stamp--date-fn data) nil) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (setq erc-stamp--date-stamps - (cl-sort (cons data erc-stamp--date-stamps) #'time-less-p - :key #'erc-stamp--date-ts)) - (setq erc-stamp--deferred-date-stamp nil) - (let* ((aligned (erc-stamp--time-as-day ct)) - (erc-stamp--current-time aligned) - (erc--msg-props (map-into '((erc--msg . datestamp) - (erc--skip track)) - 'hash-table)) - (erc-insert-post-hook - `(,(lambda () - (set-marker marker (point-min)) - (set-marker-insertion-type marker t) - (erc--hide-message 'timestamp)) - ,@(ensure-list erc-insert-post-hook))) - (erc-insert-timestamp-function - #'erc-stamp--propertize-left-date-stamp) - (pos (erc-stamp--find-insertion-point marker aligned)) - ;; - erc-timestamp-format erc-away-timestamp-format) - (erc--with-spliced-insertion pos - (erc-display-message nil nil (current-buffer) rendered)) - (setf (erc-stamp--date-ts data) aligned)) - (setq erc-timestamp-last-inserted-left rendered))))) - (add-hook hook-var symbol -90))) - -(defun erc-stamp--defer-date-insertion-on-post-insert () - (erc-stamp--defer-date-insertion-on-post-modify 'erc-timer-hook)) - -(defun erc-stamp--defer-date-insertion-on-post-send () - (erc-stamp--defer-date-insertion-on-post-modify 'erc-send-completed-hook)) - -;; This minor mode is hopefully just a placeholder because it's quite -;; unhelpful for managing complexity. A useful version would exist as -;; a standalone module to allow completely decoupling from and -;; possibly deprecating `erc-insert-timestamp-left-and-right'. -(define-minor-mode erc-stamp--date-mode - "When enabled, insert date stamps as standalone messages. -Only do so when `erc-insert-timestamp-function' is set to -`erc-insert-timestamp-left-and-right'. On `erc-insert-modify-hook', -hold off on inserting a date stamp immediately because that would force -other members of the hook to rely on heuristics and implementation -details to detect a prepended stamp's presence, not to mention -compromise the integrity of the `erc-parsed' text property. Instead, -tell `erc-insert-post-hook', via `erc-stamp--deferred-date-stamp', to -schedule a date stamp for insertion on the next go around of -`erc-timer-hook', which only runs on server-sent messages. Expect users -to know that non-server-sent messages, such as local informational -messages, won't induce a date stamp's insertion but will instead defer -it until the next arrival, which can include \"PING\"s or messages that -otherwise don't insert anything, such as those skipped on account of -`erc-ignore'." - :interactive nil - (if erc-stamp--date-mode - (progn - (add-function :around - (local 'erc-networks--transplant-target-buffer-function) - #'erc-stamp--dedupe-date-stamps-from-target-buffer) - (add-hook 'erc-networks--copy-server-buffer-functions - #'erc-stamp--dedupe-date-stamps-from-buffer 0 t) - (add-hook 'erc-insert-post-hook - #'erc-stamp--defer-date-insertion-on-post-insert 0 t) - (add-hook 'erc-send-post-hook - #'erc-stamp--defer-date-insertion-on-post-send 0 t)) - (kill-local-variable 'erc-timestamp-last-inserted-left) - (remove-function (local 'erc-networks--transplant-target-buffer-function) - #'erc-stamp--dedupe-date-stamps-from-target-buffer) - (remove-hook 'erc-networks--copy-server-buffer-functions - #'erc-stamp--dedupe-date-stamps-from-buffer t) - (remove-hook 'erc-insert-post-hook - #'erc-stamp--defer-date-insertion-on-post-insert t) - (remove-hook 'erc-send-post-hook - #'erc-stamp--defer-date-insertion-on-post-send t))) - -(defvar erc-stamp-prepend-date-stamps-p nil - "When non-nil, date stamps are not independent messages. -This flag restores pre-5.6 behavior in which date stamps were -prepended to normal chat messages. Beware that enabling -this degrades the user experience by causing 5.6+ features, like -`fill-wrap', dynamic invisibility, etc., to malfunction. When -non-nil, none of the newline twiddling mentioned in the doc -string for `erc-timestamp-format-left' occurs. That is, ERC does -not append or remove trailing newlines.") -(make-obsolete-variable 'erc-stamp-prepend-date-stamps-p - "unsupported legacy behavior" "30.1") - -(defun erc-insert-timestamp-left-and-right (string) - "Insert a stamp on either side when it changes. -When the deprecated option `erc-timestamp-format-right' is nil, -use STRING, which originates from `erc-timestamp-format', for the -right-hand stamp. Use `erc-timestamp-format-left' for formatting -the left-sided \"date stamp,\" and expect it to change less -frequently. Include all but the final trailing newline present -in the latter (if any) as part of the `erc-timestamp' field. -Allow the stamp's `invisible' property to span that same interval -but also cover the previous newline, in order to satisfy folding -requirements related to `erc-legacy-invisible-bounds-p'. -Additionally, ensure every date stamp is identifiable as such via -the function `erc-stamp-inserting-date-stamp-p' so that internal -modules can easily distinguish between other left-sided stamps -and date stamps inserted by this function." - (unless (or erc-stamp--date-format-end erc-stamp-prepend-date-stamps-p - (and (or (null erc-timestamp-format-left) - (string-empty-p ; compat - (string-trim erc-timestamp-format-left "\n"))) - (always (erc-stamp--date-mode -1)) - (setq erc-stamp-prepend-date-stamps-p t))) - (erc-stamp--date-mode +1)) - (let* ((ct (erc-stamp--current-time)) - (ts-right (with-suppressed-warnings - ((obsolete erc-timestamp-format-right)) - (if erc-timestamp-format-right - (erc-format-timestamp ct erc-timestamp-format-right) - string)))) - ;; We should arguably be ensuring a trailing newline on legacy - ;; "prepended" date stamps as well. However, since this is a - ;; compatibility oriented code path, and pre-5.6 did no such - ;; thing, better to punt. - (if-let ((erc-stamp-prepend-date-stamps-p) - (ts-left (erc-format-timestamp ct erc-timestamp-format-left)) - ((not (string= ts-left erc-timestamp-last-inserted-left)))) - (progn - (goto-char (point-min)) - (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp - ts-left) - (insert (setq erc-timestamp-last-inserted-left ts-left))) - (when-let - (((null erc-stamp--deferred-date-stamp)) - (rendered (erc-stamp--format-date-stamp ct)) - ((not (string-equal rendered erc-timestamp-last-inserted-left))) - ((null (cl-find rendered erc-stamp--date-stamps - :test #'string= :key #'erc-stamp--date-str)))) - ;; Force `erc-insert-timestamp-right' to stamp this message. - (setq erc-timestamp-last-inserted-right nil) - (setq erc-stamp--deferred-date-stamp - (make-erc-stamp--date :ts ct :str rendered)))) - ;; insert right timestamp - (let ((erc-timestamp-only-if-changed-flag t) - (erc-timestamp-last-inserted erc-timestamp-last-inserted-right)) - (erc-insert-timestamp-right ts-right) - (setq erc-timestamp-last-inserted-right ts-right)))) - -;; for testing: (setq erc-timestamp-only-if-changed-flag nil) -(defvar erc-stamp--tz nil) - -;; Unfortunately, cursory measurements show that this function is 10x -;; slower than `erc-format-timestamp', which is perhaps -;; counterintuitive. Thus, we use the latter for our cache, and -;; perform day alignments via this function only when needed. -(defun erc-stamp--time-as-day (current-time) - "Discard hour, minute, and second info from timestamp CURRENT-TIME." - (defvar current-time-list) ; <=28 - (let* ((current-time-list) ; flag - (decoded (decode-time current-time erc-stamp--tz))) - (setf (decoded-time-second decoded) 0 - (decoded-time-minute decoded) 0 - (decoded-time-hour decoded) 0 - (decoded-time-dst decoded) -1 - (decoded-time-weekday decoded) nil - (decoded-time-zone decoded) - (and erc-stamp--tz (car (current-time-zone nil erc-stamp--tz)))) - (encode-time decoded))) ; may return an integer - -(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-stamp--tz))) - (erc-put-text-property 0 (length ts) - 'font-lock-face 'erc-timestamp-face ts) - (when erc-stamp--invisible-property - (erc-put-text-property 0 (length ts) 'invisible - erc-stamp--invisible-property ts)) - ;; N.B. Later use categories instead of this harmless, but - ;; inelegant, hack. -- BPT - (and erc-timestamp-intangible - (not erc-hide-timestamps) ; bug#11706 - (erc-put-text-property 0 (length ts) 'cursor-intangible t ts)) - ts) - "")) - -(defvar-local erc-stamp--csf-props-updated-p nil) - -(define-obsolete-function-alias 'erc-munge-invisibility-spec - #'erc-stamp--manage-local-options-state "30.1" - "Perform setup and teardown of `stamp'-owned options. - -Note that this function's role in practice has long defied its -stated mandate as claimed in a now deleted comment, which -envisioned it as evolving into a central toggle for modifying -`buffer-invisibility-spec' on behalf of options and features -ERC-wide.") -(defun erc-stamp--manage-local-options-state () - "Perform local setup and teardown for `stamp'-owned options. -For `erc-timestamp-intangible', toggle `cursor-intangible-mode'. -For `erc-echo-timestamps', integrate with `cursor-sensor-mode'. -For `erc-hide-timestamps, modify `buffer-invisibility-spec'." - (if erc-timestamp-intangible - (cursor-intangible-mode +1) ; idempotent - (when (bound-and-true-p cursor-intangible-mode) - (cursor-intangible-mode -1))) - (if erc-echo-timestamps - (progn - (unless erc-stamp--permanent-cursor-sensor-functions - (dolist (hook '(erc-insert-post-hook erc-send-post-hook)) - (add-hook hook #'erc-stamp--add-csf-on-post-modify nil t)) - (setq erc-stamp--csf-props-updated-p - (alist-get 'erc-stamp--csf-props-updated-p - (or erc--server-reconnecting erc--target-priors))) - (unless erc-stamp--csf-props-updated-p - (setq erc-stamp--csf-props-updated-p t) - ;; Spoof `erc--ts' as being non-nil. - (let ((erc--msg-props (map-into '((erc--ts . t)) 'hash-table))) - (with-silent-modifications - (erc--traverse-inserted - (point-min) erc-insert-marker - #'erc-stamp--add-csf-on-post-modify))))) - (cursor-sensor-mode +1) ; idempotent - (when (>= emacs-major-version 29) - (add-function :before-until (local 'clear-message-function) - #'erc-stamp--on-clear-message))) - (dolist (hook '(erc-insert-post-hook erc-send-post-hook)) - (remove-hook hook #'erc-stamp--add-csf-on-post-modify t)) - (kill-local-variable 'erc-stamp--csf-props-updated-p) - (when (bound-and-true-p cursor-sensor-mode) - (cursor-sensor-mode -1)) - (remove-function (local 'clear-message-function) - #'erc-stamp--on-clear-message)) - (if erc-hide-timestamps - (add-to-invisibility-spec 'timestamp) - (remove-from-invisibility-spec 'timestamp))) - -(defun erc-stamp--add-csf-on-post-modify () - "Add `cursor-sensor-functions' to narrowed buffer." - (when (erc--check-msg-prop 'erc--ts) - (put-text-property (point-min) (1- (point-max)) - 'cursor-sensor-functions '(erc--echo-ts-csf)))) - -(defun erc-stamp--setup () - "Enable or disable buffer-local `erc-stamp-mode' modifications." - (if erc-stamp-mode - (progn - (erc-stamp--manage-local-options-state) - (add-function :around (local 'erc--clear-function) - #'erc-stamp--reset-on-clear '((depth . 40)))) - (let (erc-echo-timestamps erc-hide-timestamps erc-timestamp-intangible) - (erc-stamp--manage-local-options-state)) - ;; Undo local mods from `erc-insert-timestamp-left-and-right'. - (erc-stamp--date-mode -1) ; kills `erc-timestamp-last-inserted-left' - (remove-function (local 'erc--clear-function) - #'erc-stamp--reset-on-clear) - (kill-local-variable 'erc-stamp--last-stamp) - (kill-local-variable 'erc-timestamp-last-inserted) - (kill-local-variable 'erc-timestamp-last-inserted-right) - (kill-local-variable 'erc-stamp--deferred-date-stamp) - (kill-local-variable 'erc-stamp--date-stamps) - (kill-local-variable 'erc-stamp--date-format-end))) - -(defun erc-hide-timestamps () - "Hide timestamp information from display." - (interactive) - (setq erc-hide-timestamps t) - (erc-stamp--manage-local-options-state)) - -(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-stamp--manage-local-options-state)) - -(defun erc-toggle-timestamps () - "Hide or show timestamps in ERC buffers. - -Note that timestamps can only be shown for a message using this -function if `erc-timestamp-format' was set and timestamping was -enabled when the message was inserted." - (interactive) - (if erc-hide-timestamps - (setq erc-hide-timestamps nil) - (setq erc-hide-timestamps t)) - (mapc (lambda (buffer) - (with-current-buffer buffer - (erc-stamp--manage-local-options-state))) - (erc-buffer-list))) - -(defvar-local erc-stamp--last-stamp nil) - -;; FIXME rename this to avoid confusion with IRC messages. -;; Something like `erc-stamp--on-clear-echo-area-message'. -(defun erc-stamp--on-clear-message (&rest _) - "Return `dont-clear-message' when operating inside the same stamp." - (and erc-stamp--last-stamp erc-echo-timestamps - (eq (erc--get-inserted-msg-prop 'erc--ts) erc-stamp--last-stamp) - 'dont-clear-message)) - -(defun erc-echo-timestamp (dir stamp &optional zone) - "Display timestamp of message at point in echo area. -Interactively, interpret a numeric prefix as a ZONE offset in -hours (or seconds, if its abs value is larger than 14), and -interpret a \"raw\" prefix as UTC. To specify a zone for use -with the option `erc-echo-timestamps', see the companion option -`erc-echo-timestamp-zone'." - (interactive (list nil (erc--get-inserted-msg-prop 'erc--ts) - (pcase current-prefix-arg - ((and (pred numberp) v) - (if (<= (abs v) 14) (* v 3600) v)) - (`(,_) t)))) - (if (and stamp (or (null dir) (and erc-echo-timestamps (eq 'entered dir)))) - (progn - (setq erc-stamp--last-stamp stamp) - (message (format-time-string erc-echo-timestamp-format - stamp (or zone erc-echo-timestamp-zone)))) - (when (and erc-echo-timestamps (eq 'left dir)) - (setq erc-stamp--last-stamp nil)))) - -(defun erc--echo-ts-csf (_window _before dir) - (erc-echo-timestamp dir (erc--get-inserted-msg-prop 'erc--ts))) - -(defun erc-stamp--redo-right-stamp-post-clear (_ end) - "Append new right stamp to first inserted message after END." - ;; During truncation, the last existing right stamp is often deleted - ;; regardless of `erc-timestamp-only-if-changed-flag'. As of ERC 5.6, - ;; recreating inserted messages from scratch isn't doable. (Although, - ;; attempting surgery like this is likely unwise.) - (when-let ((erc-stamp--date-mode) - ((< end (1- erc-insert-marker))) ; not a /CLEAR - (bounds (erc--get-inserted-msg-bounds (1+ end))) - (ts (get-text-property (car bounds) 'erc--ts)) - (format (with-suppressed-warnings - ((obsolete erc-timestamp-format-right)) - (or erc-timestamp-format-right erc-timestamp-format))) - (rendered (erc-format-timestamp ts format)) - ((not (equal rendered erc-timestamp-last-inserted-right))) - ((not (eq 'erc-timestamp (field-at-pos (1- (cdr bounds)))))) - (erc--msg-props (map-into `((erc--ts . ,ts)) 'hash-table))) - (save-excursion - (save-restriction - (let ((erc-timestamp-last-inserted erc-timestamp-last-inserted) - (erc-timestamp-last-inserted-right - erc-timestamp-last-inserted-right)) - (narrow-to-region (car bounds) (1+ (cdr bounds))) - (cl-assert (= ?\n (char-before (point-max)))) - (erc-add-timestamp)))))) - -(defun erc-stamp--reset-on-clear (orig beg end) - "Forget date stamps older than POS and remake newest culled. -Call ORIG, an `erc--clear-function', with BEG and END markers." - (let ((fullp (= (1- erc-insert-marker) end)) ; /CLEAR-p - (skipp (or (erc--memq-msg-prop 'erc--skip 'stamp) - (and erc--msg-prop-overrides - (memq 'stamp (alist-get 'erc--skip - erc--msg-prop-overrides))))) - (culled ())) - (when erc-stamp--date-stamps - (setq erc-stamp--date-stamps - ;; Assume `seq-filter' visits items in order. - (seq-filter (lambda (o) - (or (> (erc-stamp--date-marker o) end) - (ignore - (set-marker (erc-stamp--date-marker o) nil) - (push o culled)))) - erc-stamp--date-stamps))) - ;; Before /CLEAR'ing a data stamp, skip past last blank in headroom. - (when (and fullp culled (not skipp) (< 1 beg 3 end)) - (set-marker beg 3)) - (funcall orig beg end) - (when-let ((culled) - ((not skipp)) - (ct (erc-stamp--date-ts (car culled))) - (hook (make-symbol "temporary-hook")) - (rendered (erc-stamp--format-date-stamp ct)) - (data (make-erc-stamp--date :ts ct :str rendered))) - (cl-assert erc-stamp--date-mode) - ;; Object successfully removed from model but snapshot remains. - (cl-assert (null (cl-find rendered erc-stamp--date-stamps - :test #'string= - :key #'erc-stamp--date-str))) - (let ((erc-stamp--deferred-date-stamp data) - ;; At midnight, `rendered' may still be yesterday while - ;; `erc-timestamp-last-inserted-left' is already today. - (erc-timestamp-last-inserted-left nil)) - (erc-stamp--defer-date-insertion-on-post-modify hook) - (set-marker (erc-stamp--date-marker data) end) - (run-hooks hook) - ;; After /CLEAR'ing, remove new date stamp's trailing newline - ;; because one resides between `end' and `erc-input-marker' - ;; (originally meant to protect `erc-last-saved-position'). - (when (and fullp (= end erc-last-saved-position)) - (cl-assert (or erc--called-as-input-p (null erc--msg-props))) - (delete-region (1- end) end))) - (when fullp - (setq erc-timestamp-last-inserted-right nil - erc-timestamp-last-inserted nil))))) - -(defun erc-stamp--dedupe-date-stamps (old-stamps) - "Update `erc-stamp--date-stamps' from its counterpart OLD-STAMPS. -Assume the contents of the buffer for OLD-STAMPS have just been inserted -above the current buffer's and that the old buffer still exists so that -markers still point somewhere. For each duplicate, update the existing -marker to match the transplanted timestamp with the same date. Also -copy non-duplicate `erc-stamp--date' objects from OLD-STAMPS to the -current buffer's, maintaining order." - (let (need) - (dolist (old old-stamps) - (if-let ((new (cl-find (erc-stamp--date-str old) erc-stamp--date-stamps - :test #'string= :key #'erc-stamp--date-str)) - (new-marker (erc-stamp--date-marker new))) - ;; The new buffer now has a duplicate stamp, so remove the - ;; "newer" one from the buffer. - (progn - (erc--delete-inserted-message-naively new-marker) - (set-marker new-marker (erc-stamp--date-marker old))) - ;; The new buffer doesn't have this stamp, so add its data - ;; object to the sorted list. - (push old need) - ;; Update the old marker position to point to the new buffer. - (set-marker (erc-stamp--date-marker old) - (erc-stamp--date-marker old)))) - ;; These *should* already be sorted. - (setq erc-stamp--date-stamps - (nconc (nreverse need) erc-stamp--date-stamps)))) - -(defun erc-stamp--dedupe-date-stamps-from-buffer (old-buffer) - "Merge date stamps from OLD-BUFFER into in the current buffer." - (let ((old-stamps (buffer-local-value 'erc-stamp--date-stamps old-buffer))) - (erc-stamp--dedupe-date-stamps old-stamps))) - -(defun erc-stamp--dedupe-date-stamps-from-target-buffer (orig old-buffer - new-buffer) - "Merge date stamps from OLD-BUFFER into NEW-BUFFER after calling ORIG." - (let ((old-stamps (buffer-local-value 'erc-stamp--date-stamps old-buffer))) - (prog1 (funcall orig old-buffer new-buffer) - (with-current-buffer new-buffer - (erc-stamp--dedupe-date-stamps old-stamps))))) - -(provide 'erc-stamp) - -;;; erc-stamp.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-status-sidebar.el b/lisp/erc/erc-status-sidebar.el deleted file mode 100644 index b725f98b0a1..00000000000 --- a/lisp/erc/erc-status-sidebar.el +++ /dev/null @@ -1,612 +0,0 @@ -;;; erc-status-sidebar.el --- HexChat-like activity overview for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2017, 2020-2025 Free Software Foundation, Inc. - -;; Author: Andrew Barbarello -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://github.com/drewbarbs/erc-status-sidebar - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This package provides a HexChat-like sidebar for joined channels in -;; ERC. It relies on the `erc-track' module, and displays all of the -;; same information that `erc-track' does in the mode line, but in an -;; alternative format in form of a sidebar. - -;; Shout out to sidebar.el -;; and outline-toc.el for -;; the sidebar window management ideas. - -;; Usage: - -;; Use M-x erc-status-sidebar-open RET to open the ERC status sidebar -;; in the current frame. Make sure that the `erc-track' module is -;; active (this is the default). - -;; Use M-x erc-status-sidebar-close RET to close the sidebar on the -;; current frame. With a prefix argument, it closes the sidebar on -;; all frames. - -;; Use M-x erc-status-sidebar-kill RET to kill the sidebar buffer and -;; close the sidebar on all frames. - -;; In addition to the commands above, you can also try the all-in-one -;; entry point `erc-bufbar-mode'. See its doc string for usage. - -;; If you want the status sidebar enabled whenever you use ERC, add -;; `bufbar' to `erc-modules'. Note that this library also has a major -;; mode, `erc-status-sidebar-mode', which is for internal use. - -;;; Code: - -(require 'erc) -(require 'erc-track) -(require 'fringe) -(require 'seq) - -(defgroup erc-status-sidebar nil - "A responsive side window listing all connected ERC buffers. -More commonly known as a window list or \"buflist\", this side -panel displays clickable buffer names for switching to with the -mouse. By default, ERC highlights the name corresponding to the -selected window's buffer, if any. In this context, \"connected\" -just means associated with the same IRC session, even one that -has ceased communicating with its server. For information on how -the window itself works, see Info node `(elisp) Side Windows'." - :group 'erc) - -(defcustom erc-status-sidebar-buffer-name "*ERC Status*" - "Name of the sidebar buffer." - :type 'string) - -(defcustom erc-status-sidebar-mode-line-format "ERC Status" - "Mode line format for the status sidebar." - :type 'string) - -(defcustom erc-status-sidebar-header-line-format nil - "Header line format for the status sidebar." - :type '(choice (const :tag "No header line" nil) - string)) - -(defcustom erc-status-sidebar-width 15 - "Default width of the sidebar (in columns)." - :type 'number) - -(defcustom erc-status-sidebar-channel-sort - 'erc-status-sidebar-default-chansort - "Sorting function used to determine order of channels in the sidebar." - :type 'function) - -(defcustom erc-status-sidebar-channel-format - 'erc-status-sidebar-default-chan-format - "Function used to format channel names for display in the sidebar. -Only consulted for certain values of `erc-status-sidebar-style'." - :type 'function) - -(defcustom erc-status-sidebar-highlight-active-buffer t - "Whether to highlight the selected window's buffer in the sidebar. -ERC uses the same instance across all frames. May not be -compatible with all values of `erc-status-sidebar-style'." - :package-version '(ERC . "5.6") - :type 'boolean) - -(defcustom erc-status-sidebar-style 'all-queries-first - "Preset style for rendering the sidebar. - -When set to `channels-only', ERC limits the items in the -status bar to uniquified channels. It uses the options -and functions - - `erc-channel-list', - `erc-status-sidebar-channel-sort', - `erc-status-sidebar-get-channame', - `erc-status-sidebar-channel-format' - `erc-status-sidebar-default-insert' - -for selecting, formatting, naming, and inserting entries. When -set to one of the various `all-*' values, such as `all-mixed', -ERC shows channels and queries under their respective server -buffers, using the functions - - `erc-status-sidebar-all-target-buffers', - `erc-status-sidebar-default-allsort', - `erc-status-sidebar-prefer-target-as-name', - `erc-status-sidebar-default-chan-format', - `erc-status-sidebar-pad-hierarchy' - -for the above-mentioned purposes. ERC also accepts a list of -functions to perform these roles a la carte. Since the members -of the above sets aren't really interoperable, we don't offer -them here as customization choices, but you can still specify -them manually. See doc strings for a description of their -expected arguments and return values." - :package-version '(ERC . "5.6") - :type '(choice (const channels-only) - (const all-mixed) - (const all-queries-first) - (const all-channels-first) - (list (function :tag "Buffer lister") - (function :tag "Buffer sorter") - (function :tag "Name extractor") - (function :tag "Name formatter") - (function :tag "Name inserter")))) - -(defcustom erc-status-sidebar-click-display-action t - "How to display a buffer when clicked. -Values can be anything recognized by `display-buffer' for its -ACTION parameter." - :package-version '(ERC . "5.6") - :type '(choice (const :tag "Always use/create other window" t) - (const :tag "Let `display-buffer' decide" nil) - (const :tag "Same window" (display-buffer-same-window - (inhibit-same-window . nil))) - (cons :tag "Action" - (choice function (repeat function)) - (alist :tag "Action arguments" - :key-type symbol - :value-type (sexp :tag "Value"))))) - -(defvar erc-status-sidebar--singular-p t - "Whether to restrict the sidebar to a single frame. -This variable only affects `erc-bufbar-mode'. Disabling it does -not arrange for automatically showing the sidebar in all frames. -Rather, disabling it allows for displaying the sidebar in the -selected frame even if it's already showing in some other frame.") - -(defvar hl-line-mode) -(declare-function hl-line-highlight "hl-line" nil) - -(defun erc-status-sidebar-display-window () - "Display the status buffer in a side window. Return the new window." - (display-buffer - (erc-status-sidebar-get-buffer) - `(display-buffer-in-side-window . ((side . left) - (window-width . ,erc-status-sidebar-width))))) - -(defun erc-status-sidebar-get-window (&optional no-creation) - "Return the created/existing window displaying the status buffer. - -If NO-CREATION is non-nil, the window is not created." - (let ((sidebar-window (get-buffer-window erc-status-sidebar-buffer-name - erc-status-sidebar--singular-p))) - (unless (or sidebar-window no-creation) - (with-current-buffer (erc-status-sidebar-get-buffer) - (setq-local vertical-scroll-bar nil)) - (setq sidebar-window (erc-status-sidebar-display-window)) - (set-window-dedicated-p sidebar-window t) - (set-window-parameter sidebar-window 'no-delete-other-windows t) - ;; Don't cycle to this window with `other-window'. - (set-window-parameter sidebar-window 'no-other-window t) - (setq cursor-type nil) - (set-window-fringes sidebar-window 0 0) - ;; Set a custom display table so the window doesn't show a - ;; truncation symbol when a channel name is too big. - (let ((dt (make-display-table))) - (set-window-display-table sidebar-window dt) - (set-display-table-slot dt 'truncation ?\ ))) - sidebar-window)) - -(defun erc-status-sidebar-buffer-exists-p () - "Check if the sidebar buffer exists." - (get-buffer erc-status-sidebar-buffer-name)) - -(defun erc-status-sidebar-get-buffer () - "Return the sidebar buffer, creating it if it doesn't exist." - (get-buffer-create erc-status-sidebar-buffer-name)) - -(defun erc-status-sidebar-close (&optional all-frames) - "Close the sidebar. - -If called with prefix argument (ALL-FRAMES non-nil), the sidebar -will be closed on all frames. - -The erc-status-sidebar buffer is left alone, but the window -containing it on the current frame is closed. See -`erc-status-sidebar-kill'." - (interactive "P") - (mapcar #'delete-window ; FIXME use `mapc'. - (get-buffer-window-list (erc-status-sidebar-get-buffer) - nil (if all-frames t)))) - -(defmacro erc-status-sidebar-writable (&rest body) - "Make the status buffer writable while executing BODY." - `(let ((buffer-read-only nil)) - ,@body)) - -(defun erc-status-sidebar--open () - "Maybe open the sidebar, respecting `erc-status-sidebar--singular-p'." - (save-excursion - (if (erc-status-sidebar-buffer-exists-p) - (erc-status-sidebar-get-window) - (with-current-buffer (erc-status-sidebar-get-buffer) - (erc-status-sidebar-mode) - (erc-status-sidebar-refresh))))) - -;;;###autoload(autoload 'erc-bufbar-mode "erc-status-sidebar" nil t) -(define-erc-module bufbar nil - "Show `erc-track'-like activity in a side window. -When enabling, show the sidebar immediately in the current frame -if called from a connected ERC buffer. Otherwise, arrange for -doing so on connect or whenever next displaying a new ERC buffer. -When disabling, hide the status window in all frames. With a -negative prefix arg, also shutdown the session. Normally, this -module only allows one sidebar window in an Emacs session. To -override this, use `erc-status-sidebar-open' to force creation -and `erc-status-sidebar-close' to hide a single instance on the -current frame only." - ((unless erc-track-mode - (unless (memq 'track erc-modules) - (erc--warn-once-before-connect 'erc-bufbar-mode - "Module `bufbar' needs global module `track'. Enabling now." - " This will affect \C-]all\C-] ERC sessions." - " Add `track' to `erc-modules' to silence this message.")) - (erc-track-mode +1)) - (add-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) - ;; Preserve side-window dimensions after `custom-buffer-done'. - (when-let (((not erc--updating-modules-p)) - (buf (or (and (derived-mode-p 'erc-mode) (current-buffer)) - (car (erc-buffer-filter - (lambda () erc-server-connected)))))) - (with-current-buffer buf - (erc-status-sidebar--open)))) - ((remove-hook 'erc--setup-buffer-hook #'erc-status-sidebar--open) - (erc-status-sidebar-close 'all-frames) - (when-let ((arg erc--module-toggle-prefix-arg) - ((numberp arg)) - ((< arg 0))) - (erc-status-sidebar-kill)))) - -;;;###autoload -(defun erc-status-sidebar-open () - "Open or create a sidebar window in the current frame. -When `erc-bufbar-mode' is active, do this even if one already -exists in another frame." - (interactive) - (let ((erc-status-sidebar--singular-p (not erc-bufbar-mode))) - (erc-status-sidebar--open))) - -;;;###autoload -(defun erc-status-sidebar-toggle () - "Toggle the sidebar open/closed on the current frame. -When opening, and `erc-bufbar-mode' is active, create a sidebar -even if one already exists in another frame." - (interactive) - (if (get-buffer-window erc-status-sidebar-buffer-name nil) - (erc-status-sidebar-close) - (erc-status-sidebar-open))) - -(defun erc-status-sidebar-get-channame (buffer) - "Return name of BUFFER with all leading \"#\" characters removed." - (let ((s (buffer-name buffer))) - (if (string-match "^#\\{1,2\\}" s) - (setq s (replace-match "" t t s))) - (downcase s))) - -(defun erc-status-sidebar-default-chansort (chanlist) - "Sort CHANLIST case-insensitively for display in the sidebar." - (sort chanlist (lambda (x y) - (string< (erc-status-sidebar-get-channame x) - (erc-status-sidebar-get-channame y))))) - -(defvar erc-status-sidebar--trimpat nil) -(defvar erc-status-sidebar--prechan nil) - -(defun erc-status-sidebar-prefer-target-as-name (buffer) - "Return some name to represent buffer in the sidebar." - (if-let ((target (buffer-local-value 'erc--target buffer))) - (cond ((and erc-status-sidebar--trimpat (erc--target-channel-p target)) - (string-trim-left (erc--target-string target) - erc-status-sidebar--trimpat)) - ((and erc-status-sidebar--prechan (erc--target-channel-p target)) - (concat erc-status-sidebar--prechan - (erc--target-string target))) - (t (erc--target-string target))) - (buffer-name buffer))) - -;; This could be converted into an option if people want. -(defvar erc-status-sidebar--show-disconnected t) - -(defun erc-status-sidebar-all-target-buffers (process) - (erc-buffer-filter (lambda () - (and erc--target - (or erc-status-sidebar--show-disconnected - (erc-server-process-alive)))) - process)) - -;; FIXME profile this. Rebuilding the graph every time track updates -;; seems wasteful for occasions where server messages are processed -;; unthrottled, such as during history playback. If it's a problem, -;; we should look into rewriting this using `ewoc' or some other -;; solution that maintains a persistent model. -(defun erc-status-sidebar-default-allsort (target-buffers) - "Return a list of servers interspersed with their targets." - (mapcan (pcase-lambda (`(,proc . ,chans)) - (cons (process-buffer proc) - (let ((erc-status-sidebar--trimpat - (and (eq erc-status-sidebar-style 'all-mixed) - (with-current-buffer (process-buffer proc) - (when-let ((ch-pfxs (erc--get-isupport-entry - 'CHANTYPES 'single))) - (regexp-quote ch-pfxs))))) - (erc-status-sidebar--prechan - (and (eq erc-status-sidebar-style - 'all-queries-first) - "\C-?"))) - (sort chans - (lambda (x y) - (string< - (erc-status-sidebar-prefer-target-as-name x) - (erc-status-sidebar-prefer-target-as-name y))))))) - (sort (seq-group-by (lambda (b) - (buffer-local-value 'erc-server-process b)) - target-buffers) - (lambda (a b) - (string< (buffer-name (process-buffer (car a))) - (buffer-name (process-buffer (car b)))))))) - -(defvar-local erc-status-sidebar--active-marker nil - "Marker indicating currently active buffer.") - -(defun erc-status-sidebar--set-active-line (erc-buffer) - (when (and erc-status-sidebar-highlight-active-buffer - (eq (window-buffer (and (minibuffer-window-active-p - (selected-window)) - (minibuffer-selected-window))) - erc-buffer)) - (set-marker erc-status-sidebar--active-marker (point)))) - -(defun erc-status-sidebar-default-insert (channame chanbuf _chanlist) - "Insert CHANNAME followed by a newline. -Maybe arrange to highlight line if CHANBUF is showing in the -focused window." - (erc-status-sidebar--set-active-line chanbuf) - (insert channame "\n")) - -(defun erc-status-sidebar-pad-hierarchy (bufname buffer buflist) - "Prefix BUFNAME to emphasize BUFFER's role in BUFLIST." - (if (and (buffer-live-p buffer) (buffer-local-value 'erc--target buffer)) - (insert " ") - (unless (eq buffer (car buflist)) - (insert "\n"))) ; ^L - (when bufname - (erc-status-sidebar--set-active-line buffer)) - (insert (or bufname - (and-let* (((not (buffer-live-p buffer))) - (next (cadr (member buffer buflist))) - ((buffer-live-p next)) - (proc (buffer-local-value 'erc-server-process next)) - (id (process-get proc 'erc-networks--id)) - ((erc-networks--id-string id)))) - "???") - "\n")) - -(defun erc-status-sidebar-default-chan-format (channame - &optional num-messages erc-face) - "Format CHANNAME for display in the sidebar. - -If NUM-MESSAGES is non-nil, append it to the channel name. If -ERC-FACE is non-nil, apply it to channel name. If it is equal to -`erc-default-face', also apply bold property to make the channel -name stand out." - (when num-messages - (setq channame (format "%s [%d]" channame num-messages))) - (when erc-face - (put-text-property 0 (length channame) 'face erc-face channame) - (when (eq erc-face 'erc-default-face) - (add-face-text-property 0 (length channame) 'bold t channame))) - channame) - -(defun erc-status-sidebar-refresh () - "Update the content of the sidebar." - (interactive) - (pcase-let* ((`(,list-fn ,sort-fn ,name-fn ,fmt-fn ,insert-fn) - (pcase erc-status-sidebar-style - ('channels-only (list #'erc-channel-list - erc-status-sidebar-channel-sort - #'erc-status-sidebar-get-channame - erc-status-sidebar-channel-format - #'erc-status-sidebar-default-insert)) - ((or 'all-mixed 'all-queries-first 'all-channels-first) - '(erc-status-sidebar-all-target-buffers - erc-status-sidebar-default-allsort - erc-status-sidebar-prefer-target-as-name - erc-status-sidebar-default-chan-format - erc-status-sidebar-pad-hierarchy)) - (v v))) - (chanlist (apply sort-fn (funcall list-fn nil) nil)) - (windows nil)) - (with-current-buffer (erc-status-sidebar-get-buffer) - (dolist (window (get-buffer-window-list nil nil t)) - (push (cons window (window-start window)) windows)) - (erc-status-sidebar-writable - (delete-region (point-min) (point-max)) - (goto-char (point-min)) - (if erc-status-sidebar--active-marker - (set-marker erc-status-sidebar--active-marker nil) - (setq erc-status-sidebar--active-marker (make-marker))) - (dolist (chanbuf chanlist) - (let* ((tup (seq-find (lambda (tup) (eq (car tup) chanbuf)) - erc-modified-channels-alist)) - (count (if tup (cadr tup))) - (face (if tup (cddr tup))) - (face (if (or (not (buffer-live-p chanbuf)) - (not (erc-server-process-alive chanbuf))) - `(shadow ,face) - face)) - (channame (apply fmt-fn - (copy-sequence (funcall name-fn chanbuf)) - count face nil)) - (cnlen (length channame))) - (put-text-property 0 cnlen 'erc-buf chanbuf channame) - (put-text-property 0 cnlen 'mouse-face 'highlight channame) - (put-text-property - 0 cnlen 'help-echo - "mouse-1: switch to buffer in other window" channame) - (funcall insert-fn channame chanbuf chanlist))) - (when windows - (map-apply #'set-window-start windows)) - (when (and erc-status-sidebar-highlight-active-buffer - (marker-buffer erc-status-sidebar--active-marker)) - (goto-char erc-status-sidebar--active-marker) - (require 'hl-line) - (unless hl-line-mode (hl-line-mode +1)) - (hl-line-highlight)))))) - -(defun erc-status-sidebar-kill () - "Close the ERC status sidebar and its buffer." - (interactive) - (when (and erc-bufbar-mode (not erc--module-toggle-prefix-arg)) - (erc-bufbar-mode -1)) - (ignore-errors (kill-buffer erc-status-sidebar-buffer-name))) - -(defun erc-status-sidebar-click (event) - "Handle click EVENT in `erc-status-sidebar-mode-map'." - (interactive "e") - (save-excursion - (let ((window (posn-window (event-start event))) - (pos (posn-point (event-end event)))) - ;; Current buffer is "ERC Status" and its window is selected - (cl-assert (eq major-mode 'erc-status-sidebar-mode)) - (cl-assert (eq (selected-window) window)) - (cl-assert (eq (window-buffer window) (current-buffer))) - (when-let ((buf (get-text-property pos 'erc-buf))) - ;; Option operates relative to last selected window - (select-window (get-mru-window nil nil 'not-selected)) - (pop-to-buffer buf erc-status-sidebar-click-display-action))))) - -(defun erc-status-sidebar-scroll-up (lines) - "Scroll sidebar buffer's content LINES linse upward. -If LINES is nil, scroll up a full screen's worth." - (interactive "P") - (let ((other-window-scroll-buffer (erc-status-sidebar-get-buffer))) - (scroll-other-window lines))) - -(defun erc-status-sidebar-scroll-down (lines) - "Scroll sidebar buffer's content LINES lines downward. -If LINES is nil, scroll down a full screen's worth." - (interactive "P") - (let ((other-window-scroll-buffer (erc-status-sidebar-get-buffer))) - (scroll-other-window-down lines))) - -(defun erc-status-sidebar-recenter (arg) - "Recenter the status sidebar. -Expect `erc-status-sidebar-highlight-active-buffer' to be non-nil -and to be invoked in a buffer matching the line currently -highlighted." - (interactive "P") - (let* ((buf (erc-status-sidebar-get-buffer)) - (win (get-buffer-window buf))) - (with-current-buffer buf - (when (and erc-status-sidebar--active-marker - (marker-position erc-status-sidebar--active-marker)) - (with-selected-window win - (goto-char erc-status-sidebar--active-marker) - (recenter arg t)))))) - -(defvar erc-status-sidebar-mode-map - (let ((map (make-sparse-keymap))) - (set-keymap-parent map special-mode-map) - (define-key map [mouse-1] #'erc-status-sidebar-click) - map)) - -(defvar erc-status-sidebar-refresh-triggers - '(erc-track-list-changed-hook - erc-join-hook - erc-part-hook - erc-kill-buffer-hook - erc-kill-channel-hook - erc-kill-server-hook - erc-kick-hook - erc-disconnected-hook - erc-quit-hook) - "Hooks to refresh the sidebar on. -This may be set locally in the status-sidebar buffer under -various conditions, like when the option -`erc-status-sidebar-highlight-active-buffer' is non-nil.") - -(defvar erc-status-sidebar--highlight-refresh-triggers - '(window-selection-change-functions) - "Triggers enabled with `erc-status-sidebar-highlight-active-buffer'.") - -(defun erc-status-sidebar--refresh-unless-input () - "Run `erc-status-sidebar-refresh' unless there are unread commands. -Also abstain when the user is interacting with the minibuffer." - (unless (or (input-pending-p) (minibuffer-window-active-p (selected-window))) - (erc-status-sidebar-refresh))) - -(defun erc-status-sidebar--post-refresh (&rest _ignore) - "Schedule sidebar refresh for execution after command stack is cleared. - -Ignore arguments in IGNORE, allowing this function to be added to -hooks that invoke it with arguments." - (run-at-time 0 nil #'erc-status-sidebar--refresh-unless-input)) - -(defun erc-status-sidebar-mode--unhook () - "Remove hooks installed by `erc-status-sidebar-mode'." - (dolist (hk erc-status-sidebar-refresh-triggers) - (remove-hook hk #'erc-status-sidebar--post-refresh)) - (remove-hook 'window-configuration-change-hook - #'erc-status-sidebar-set-window-preserve-size)) - -(defun erc-status-sidebar-set-window-preserve-size () - "Tell Emacs to preserve the current height/width of the ERC sidebar window. - -Note that preserve status needs to be reset when the window is -manually resized, so `erc-status-sidebar-mode' adds this function -to the `window-configuration-change-hook'." - (when (and (eq (selected-window) (let (erc-status-sidebar--singular-p) - (erc-status-sidebar-get-window))) - (fboundp 'window-preserve-size)) - (unless (eq (window-total-width) (window-min-size nil t)) - (apply #'window-preserve-size (selected-window) t t nil)))) - -(define-derived-mode erc-status-sidebar-mode special-mode "ERC Sidebar" - "Major mode for ERC status sidebar." - ;; Users invoking M-x erc-status-sidebar-mode most likely expect to - ;; summon the module's minor-mode, `erc-bufbar-mode'. - :interactive nil - ;; Don't scroll the buffer horizontally, if a channel name is - ;; obscured then the window can be resized. - (setq-local auto-hscroll-mode nil) - (setq cursor-type nil - buffer-read-only t - mode-line-format erc-status-sidebar-mode-line-format - header-line-format erc-status-sidebar-header-line-format) - (erc-status-sidebar-set-window-preserve-size) - - (add-hook 'window-configuration-change-hook - #'erc-status-sidebar-set-window-preserve-size nil t) - (when erc-status-sidebar-highlight-active-buffer - (setq-local erc-status-sidebar-refresh-triggers - `(,@erc-status-sidebar--highlight-refresh-triggers - ,@erc-status-sidebar-refresh-triggers))) - (dolist (hk erc-status-sidebar-refresh-triggers) - (add-hook hk #'erc-status-sidebar--post-refresh)) - - ;; `change-major-mode-hook' is run *before* the - ;; erc-status-sidebar-mode initialization code, so it won't undo the - ;; add-hook's we did in the previous expressions. - (add-hook 'change-major-mode-hook #'erc-status-sidebar-mode--unhook nil t) - (add-hook 'kill-buffer-hook #'erc-status-sidebar-mode--unhook nil t)) - -(provide 'erc-status-sidebar) -;;; erc-status-sidebar.el ends here - -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el deleted file mode 100644 index c52ec4c77f6..00000000000 --- a/lisp/erc/erc-track.el +++ /dev/null @@ -1,1262 +0,0 @@ -;;; erc-track.el --- Track modified channel buffers -*- lexical-binding:t -*- - -;; Copyright (C) 2002-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; Keywords: comm -;; URL: https://www.emacswiki.org/emacs/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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; Highlights keywords and pals (friends), and hides or highlights fools -;; (using a dark color). Add to your init file: - -;; (require 'erc-track) -;; (erc-track-mode 1) - -;; Todo: -;; * Add extensibility so that custom functions can track -;; custom modification types. - -(eval-when-compile (require 'cl-lib)) -(require 'erc) -(require 'erc-match) - -;;; Code: - -(defgroup erc-track nil - "Track active buffers and show activity in the mode line." - :group 'erc) - -(defcustom erc-track-enable-keybindings 'ask - "Whether to enable the ERC track keybindings, namely: -\\`C-c C-SPC' and \\`C-c C-@', which both do the same thing. - -The default is to check to see whether these keys are used -already: if not, then enable the ERC track minor mode, which -provides these keys. Otherwise, do not touch the keys. - -This can alternatively be set to either t or nil, which indicate -respectively always to enable ERC track minor mode or never to -enable ERC track minor mode. - -The reason for using this default value is to both (1) adhere to -the Emacs development guidelines which say not to touch keys of -the form C-c C- and also (2) to meet the expectations -of long-time ERC users, many of whom rely on these keybindings." - :type '(choice (const :tag "Ask, if used already" ask) - (const :tag "Enable" t) - (const :tag "Disable" nil))) - -(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'. - -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." - :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 is visible" - selected-visible))) - -(defcustom erc-track-exclude nil - "A list targets (channel names or query targets) which should not be tracked." - :type '(repeat string)) - -(defcustom erc-track-remove-disconnected-buffers nil - "If true, remove buffers associated with a server that is -disconnected from `erc-modified-channels-alist'." - :type 'boolean) - -(defcustom erc-track-exclude-types '("NICK" "333" "353") - "List of message types to be ignored. -This list could look like (\"JOIN\" \"PART\"). - -By default, exclude changes of nicknames (NICK), display of who -set the channel topic (333), and listing of users on the current -channel (353)." - :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." - :type 'boolean) - -(defcustom erc-track-shorten-start 1 - "Minimum number of characters for a channel name in the mode-line." - :type 'number) - -(defcustom erc-track-shorten-cutoff 4 - "All channel names longer than this value will be shortened." - :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 two 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'." - :type '(choice (const :tag "No" nil) - (const :tag "Yes" t) - (const :tag "Max" max))) - -(defcustom erc-track-shorten-function 'erc-track-shorten-names - "Function 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." - :type '(choice (const :tag "Disabled") - function)) - -(defcustom erc-track-list-changed-hook nil - "Hook run when the contents of `erc-modified-channels-alist' changes. - -This is useful for people that don't use the default mode-line -notification but instead use a separate mechanism to provide -notification of channel activity." - :type 'hook) - -(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.)" - :type 'boolean) - -;; In an emergency, users can opt out of this migration with: -;; -;; (put 'erc-track-faces-priority-list 'erc-track--obsolete-faces t) -;; (put 'erc-track-faces-normal-list 'erc-track--obsolete-faces t) -;; -(defun erc-track--massage-nick-button-faces (sym val &optional set-fn) - "Transform VAL of face-list option SYM to remove/replace obsolete items. -Use `set'-compatible SET-FN when given. Record any migrations as cons -cells of (OLD . NEW) in the symbol property `erc-track--obsolete-faces' -of SYM." - (let* ((oldface '(erc-nick-default-face erc-default-face)) - (newface '(erc-button-nick-default-face erc-default-face)) - (migrations (get sym 'erc-track--obsolete-faces)) - (new (if migrations - val - (delq nil - (mapcar - (lambda (f) - (if (equal f oldface) - (setf (alist-get oldface migrations - nil nil #'equal) - (and (not (member newface val)) newface)) - f)) - val))))) - (when migrations - (put sym 'erc-track--obsolete-faces migrations)) - (if set-fn (funcall set-fn sym new) (set-default sym new)))) - -(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-default-face) - erc-dangerous-host-face - erc-nick-default-face - (erc-button-nick-default-face erc-nick-default-face) - (erc-button-nick-default-face erc-default-face) - erc-default-face - erc-action-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 mode line. -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. - -Note that ERC prioritizes certain faces reserved for critical -messages regardless of this option's value." - :package-version '(ERC . "5.6.1") - :set #'erc-track--massage-nick-button-faces - :type (erc--with-dependent-type-match - (repeat (choice face (repeat :tag "Combination" face))) - erc-button)) - -(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." - :type '(choice (const nil) - (repeat string) - (const all))) - -(defcustom erc-track-faces-normal-list - '((erc-button erc-default-face) - erc-dangerous-host-face - erc-nick-default-face - (erc-button-nick-default-face erc-nick-default-face) - (erc-button-nick-default-face erc-default-face) - erc-default-face - erc-notice-face - erc-action-face) - "A list of faces considered to be part of normal conversations. -This list is used to highlight active buffer names in the mode line. - -If a message contains one of the faces in this list, and the -previous mode line face for this buffer is also in this list, then -the buffer name will be highlighted using the face from the -message. This gives a rough indication that active conversations -are occurring in these channels. - -Note that ERC makes a copy of this option when initializing the -module. To see your changes reflected mid-session, cycle -\\[erc-track-mode]. - -The effect may be disabled by setting this variable to nil." - :package-version '(ERC . "5.6.1") - :set #'erc-track--massage-nick-button-faces - :type (erc--with-dependent-type-match - (repeat (choice face (repeat :tag "Combination" face))) - erc-button)) - -(defvar erc-track-ignore-normal-contenders-p nil - "Compatibility flag to promote only exclusively new \"normal\" faces. -When non-nil, revert to pre-5.6 behavior in which only a current -mode-line face that both outranks and is absent from the current -message is eligible for replacement by a fellow face from -`erc-track-faces-normal-list' that does appear in the message. -By extension, when enabled, never replace the current, reigning -mode-line face if it's present in the current message. May be -incompatible with modules introduced after ERC 5.5.") - -(defcustom erc-track-position-in-mode-line 'before-modes - "Where to show modified channel information in the mode-line. - -Choices are: -`before-modes' - add to the beginning of `mode-line-modes', -`after-modes' - add to the end of `mode-line-modes', -t - add to the end of `global-mode-string', -nil - don't add to mode line." - :type '(choice (const :tag "Just before mode information" before-modes) - (const :tag "Just after mode information" after-modes) - (const :tag "After all other information" t) - (const :tag "Don't display in mode line" 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 - (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) - "] " "]")) - "")) - -(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 is a list of the form (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 a face (or a list of faces, combined as usual) to use -when displaying the buffer's name in the mode line. - -Entries in this list are only added/updated for buffers that were -not visible when activity occurred in them, and are removed for -each buffer as soon as it becomes visible again (or if the server -is disconnected, provided `erc-track-remove-disconnected-buffers' -is true). - -For how the face is chosen for a buffer, see -`erc-track-select-mode-line-face' and -`erc-track-priority-faces-only'. For how buffers are then -displayed in the mode line, see `erc-modified-channels-display'.") - -(defcustom erc-track-showcount nil - "If non-nil, count of unseen messages will be shown for each channel." - :type 'boolean) - -(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) - -(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) - -(defcustom erc-track-switch-direction 'oldest - "Direction `erc-track-switch-buffer' should switch. - - importance - find buffer with the most important message - oldest - find oldest active buffer - newest - find newest active buffer - leastactive - find buffer with least unseen messages - mostactive - find buffer with most unseen messages. - -If set to `importance', the importance is determined by position -in `erc-track-faces-priority-list', where first is most -important." - :type '(choice (const importance) - (const oldest) - (const newest) - (const leastactive) - (const mostactive))) - -(defconst erc-track--attn-faces '((erc-error-face erc-notice-face)) - "Faces whose presence always triggers mode-line inclusion.") - -(defun erc-track-remove-from-mode-line () - "Remove `erc-track-modified-channels' from the mode-line." - (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 ((eq position 'before-modes) - (add-to-list 'mode-line-modes - '(t erc-modified-channels-object))) - ((eq position 'after-modes) - (add-to-list 'mode-line-modes - '(t erc-modified-channels-object) t)) - ((eq position 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 - -(defvar erc-track--shortened-names nil - "A cons of the last novel name-shortening params and the result. -The CAR is a hash of environmental inputs such as options and -parameters passed to `erc-track-shorten-function'. Its effect is -only really noticeable during batch processing.") - -(defvar erc-track--shortened-names-current-hash nil) - -(defun erc-track--shortened-names-set (_ shortened) - "Remember SHORTENED names with hash of contextual params." - (cl-assert erc-track--shortened-names-current-hash) - (setq erc-track--shortened-names - (cons erc-track--shortened-names-current-hash shortened))) - -(defun erc-track--shortened-names-get (channel-names) - "Cache CHANNEL-NAMES with various contextual parameters. -For now, omit relevant options like `erc-track-shorten-start' and -friends, even though they do affect the outcome, because they -likely change too infrequently to matter over sub-second -intervals and are unlikely to be let-bound or set locally." - (when-let ((hash (setq erc-track--shortened-names-current-hash - (sxhash-equal (list channel-names - (buffer-list) - erc-track-shorten-function)))) - (erc-track--shortened-names) - ((= hash (car erc-track--shortened-names)))) - (cdr erc-track--shortened-names))) - -(gv-define-simple-setter erc-track--shortened-names-get - erc-track--shortened-names-set) - -(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)) - -(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)) - -;;; Minor mode - -;; Play nice with other IRC clients (and Emacs development rules) by -;; making this a minor mode - -(defvar erc-track-minor-mode-map - (let ((map (make-sparse-keymap))) - (define-key map (kbd "C-c C-@") #'erc-track-switch-buffer) - (define-key map (kbd "C-c C-SPC") #'erc-track-switch-buffer) - map) - "Keymap for ERC track minor mode.") - -;;;###autoload -(define-minor-mode erc-track-minor-mode - "Toggle mode line display of ERC activity (ERC Track minor mode). - -ERC Track minor mode is a global minor mode. It exists for the -sole purpose of providing the C-c C-SPC and C-c C-@ keybindings. -Make sure that you have enabled the track module, otherwise the -keybindings will not do anything useful." - :global t) - -(defun erc-track-minor-mode-maybe (&optional buffer) - "Enable `erc-track-minor-mode', depending on `erc-track-enable-keybindings'." - (when (and (not erc-track-minor-mode) - ;; don't start the minor mode until we have an ERC - ;; process running, because we don't want to prompt the - ;; user while starting Emacs - (or (and (buffer-live-p buffer) - (with-current-buffer buffer (eq major-mode 'erc-mode))) - (erc-buffer-list))) - (cond ((eq erc-track-enable-keybindings 'ask) - (let ((key (or (and (key-binding (kbd "C-c C-SPC")) "C-SPC") - (and (key-binding (kbd "C-c C-@")) "C-@")))) - (if key - (if (y-or-n-p - (concat "The C-c " key " binding is in use;" - " override it for tracking? ")) - (progn - (message (concat "Will change it; set" - " `erc-track-enable-keybindings'" - " to disable this message")) - (sleep-for 3) - (erc-track-minor-mode 1)) - (message (concat "Not changing it; set" - " `erc-track-enable-keybindings'" - " to disable this message")) - (sleep-for 3)) - (erc-track-minor-mode 1)))) - ((eq erc-track-enable-keybindings t) - (erc-track-minor-mode 1)) - (t nil)))) - -;;; Module - -;;;###autoload(autoload 'erc-track-mode "erc-track" nil t) -(define-erc-module track nil - "This mode tracks ERC channel buffers with activity." - ;; Enable: - ((when (boundp 'erc-track-when-inactive) - (if erc-track-when-inactive - (progn - (add-hook 'window-configuration-change-hook #'erc-user-is-active) - (add-hook 'erc-send-completed-hook #'erc-user-is-active) - ;; FIXME find out why this uses `erc-server-001-functions'. - ;; `erc-user-is-active' runs when `erc-server-connected' is - ;; non-nil. But this hook usually only runs when it's nil. - (add-hook 'erc-server-001-functions #'erc-user-is-active)) - (erc-track-add-to-mode-line erc-track-position-in-mode-line) - (erc-update-mode-line) - (add-hook 'window-configuration-change-hook - #'erc-window-configuration-change) - (add-hook 'erc-insert-post-hook #'erc-track-modified-channels) - (add-hook 'erc-disconnected-hook #'erc-modified-channels-update)) - ;; enable the tracking keybindings - (add-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) - (erc-track-minor-mode-maybe)) - (add-hook 'erc-mode-hook #'erc-track--setup) - (unless erc--updating-modules-p (erc-buffer-do #'erc-track--setup)) - (add-hook 'erc-networks--copy-server-buffer-functions - #'erc-track--replace-killed-buffer)) - ;; Disable: - ((when (boundp 'erc-track-when-inactive) - (erc-track-remove-from-mode-line) - (if erc-track-when-inactive - (progn - (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) - ;; FIXME remove this if unused. - (remove-hook 'erc-timer-hook #'erc-user-is-active)) - (remove-hook 'window-configuration-change-hook - #'erc-window-configuration-change) - (remove-hook 'erc-disconnected-hook #'erc-modified-channels-update) - (remove-hook 'erc-insert-post-hook #'erc-track-modified-channels)) - ;; disable the tracking keybindings - (remove-hook 'erc-connect-pre-hook #'erc-track-minor-mode-maybe) - (when erc-track-minor-mode - (erc-track-minor-mode -1))) - (remove-hook 'erc-mode-hook #'erc-track--setup) - (erc-buffer-do #'erc-track--setup) - (remove-hook 'erc-networks--copy-server-buffer-functions - #'erc-track--replace-killed-buffer))) - -;; FIXME move this above the module definition. -(defcustom erc-track-when-inactive nil - "Enable channel tracking even for visible buffers, if you are inactive." - :type 'boolean - :set (lambda (sym val) - (if erc-track-mode - (progn - (erc-track-disable) - (set sym val) - (erc-track-enable)) - (set sym val)))) - -(defvar-local erc-track--priority-faces nil - "Local copy of `erc-track-faces-priority-list' as a hash table. -Keys are faces and values are rank integers (smaller is more important).") - -(defvar-local erc-track--normal-faces nil - "Local copy of `erc-track-faces-normal-list' as a hash table. -Keys and values are faces. The table is weak valued so it can double as -a buttonizing cache. See `erc-button-add-button' and `erc--merge-prop'.") - -(defun erc-track--setup () - "Initialize a buffer for use with the `track' module. -If this is a server buffer or either `erc-track-faces-normal-list' or -`erc-track-faces-priority-list' is locally bound, create a new cache -table with corresponding local variable `erc-track--normal-faces' or -`erc-track--priority-faces'. Otherwise, in target buffers with no local -binding, set the cache variable's local value to that of server's." - (if erc-track-mode - (let (warnp) - ;; Don't bother warning users who've disabled `button'. - (unless (or erc--target - (not (or (bound-and-true-p erc-button-mode) - (memq 'button erc-modules)))) - (dolist (opt '(erc-track-faces-normal-list - erc-track-faces-priority-list)) - (when (local-variable-p opt) - (erc-track--massage-nick-button-faces opt (symbol-value opt) - #'set)) - (when-let ((migrations (get opt 'erc-track--obsolete-faces)) - ((consp migrations))) - (push (cons opt - (mapcar (pcase-lambda (`(,old . ,new)) - (format (if new "changed %s to %s" - "removed %s") - old new)) - migrations)) - warnp) - (put opt 'erc-track--obsolete-faces nil))) - (when warnp - (pcase-dolist (`(,opt . ,migrations) warnp) - (erc--warn-once-before-connect 'erc-track-mode - "Option `%S' contains " - (if (cdr migrations) "obsolete items." "an obsolete item.") - " ERC has done the following for the current session: %s." - " Please review these changes and, if convinced," - " silence this message by saving the current value." - opt (string-join migrations ", "))))) - ;; Set `erc-track--priority-faces' cache to new or shared value. - (let* ((localp (and erc--target - (local-variable-p 'erc-track-faces-priority-list))) - (existing (erc-with-server-buffer erc-track--priority-faces)) - (table (or (and (not localp) existing) - (let ((p 0)) - (map-into - (mapcar (lambda (f) (cons f (cl-incf p))) - (append erc-track--attn-faces - erc-track-faces-priority-list)) - `(hash-table :test equal)))))) - (setq erc-track--priority-faces table) - (unless (or localp existing) - (erc-with-server-buffer (setq erc-track--priority-faces table)))) - ;; Likewise for `erc-track--normal-faces' cache. - (let* ((localp (and erc--target - (local-variable-p 'erc-track-faces-normal-list))) - (existing (erc-with-server-buffer erc-track--normal-faces)) - (table (or (and (not localp) existing) - (map-into (mapcar (lambda (f) (cons f f)) - erc-track-faces-normal-list) - `(hash-table :test equal - :weakness value))))) - (setq erc-track--normal-faces table) - (unless (or localp existing) - (erc-with-server-buffer (setq erc-track--normal-faces table))))) - (kill-local-variable 'erc-track--priority-faces) - (kill-local-variable 'erc-track--normal-faces))) - -;;; 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'." - (when erc-server-connected - (setq erc-buffer-activity (erc-current-time)) - (erc-track-modified-channels))) - -(defun erc-track-get-buffer-window (buffer frame-param) - (if (eq frame-param 'selected-visible) - (if (eq (frame-visible-p (selected-frame)) t) - (get-buffer-window buffer nil) - nil) - (get-buffer-window buffer frame-param))) - -(defun erc-buffer-visible (buffer) - "Return non-nil when the buffer is visible." - (if erc-track-when-inactive - (when erc-buffer-activity; could be nil - (and (erc-track-get-buffer-window buffer erc-track-visibility) - (not (time-less-p erc-buffer-activity-timeout - (erc-time-diff erc-buffer-activity nil))))) - (erc-track-get-buffer-window buffer erc-track-visibility))) - -;;; Tracking the channel modifications - -(defun erc-window-configuration-change () - (unless (minibuffer-window-active-p (minibuffer-window)) - ;; delay this until command has finished to make sure window is - ;; actually visible before clearing activity - (erc-modified-channels-update))) - -(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 causes changes to the -window-configuration.") - -(defun erc-modified-channels-update (&rest _args) - "Update `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) - (removed-channel nil)) - (mapc (lambda (elt) - (let ((buffer (car elt))) - (when (or (not (bufferp buffer)) - (not (buffer-live-p buffer)) - (erc-buffer-visible buffer) - (and erc-track-remove-disconnected-buffers - (not (with-current-buffer buffer - erc-server-connected)))) - (setq removed-channel t) - (erc-modified-channels-remove-buffer buffer)))) - erc-modified-channels-alist) - (when removed-channel - (erc-modified-channels-display))))) - -(defvar erc-track-mouse-face 'mode-line-highlight - "The face to use when mouse is over channel names in the mode line.") - -(defun erc-make-mode-line-buffer-name (string buffer &optional faces count) - "Return a button that switches to BUFFER when clicked. -STRING is the string in the button. It is possibly suffixed with -the number of unread messages, according to variables -`erc-track-showcount' and `erc-track-showcount-string'. - -If `erc-track-use-faces' is true and FACES are provided, format -STRING with them. When the mouse hovers above the button, STRING -is displayed according to `erc-track-mouse-face'." - ;; 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 (and count 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) - (put-text-property - 0 (length name) - 'help-echo (concat "mouse-2: switch to buffer, " - "mouse-3: switch to buffer in other window") - name) - (put-text-property 0 (length name) 'mouse-face erc-track-mouse-face 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." - (cond ((or (eq 'mostactive erc-track-switch-direction) - (eq 'leastactive erc-track-switch-direction)) - (erc-track-sort-by-activest)) - ((eq 'importance erc-track-switch-direction) - (erc-track-sort-by-importance))) - (run-hooks 'erc-track-list-changed-hook) - (when erc-track-position-in-mode-line - (let* ((oldobject erc-modified-channels-object) - (strings - (when erc-modified-channels-alist - ;; 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)) - (erc-track--shortened-names-current-hash nil) - (short-names - (if (functionp erc-track-shorten-function) - (with-memoization - (erc-track--shortened-names-get long-names) - (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))) - strings))) - (newobject (erc-modified-channels-object strings))) - (unless (equal-including-properties oldobject newobject) - (setq erc-modified-channels-object newobject) - (force-mode-line-update t))))) - -(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 (called-interactively-p 'interactive) - (erc-modified-channels-display))) - -(defun erc-track-clear () - "Clear ERC's mode-line activity indicator." - (interactive) - (setq erc-modified-channels-alist nil) - (erc-modified-channels-display)) - -(defun erc-track-find-face (faces) - "Return the face to use in the mode line." - (declare (obsolete erc-track-select-mode-line-face "28.1")) - (erc-track-select-mode-line-face (car faces) (cdr faces))) - -;; Note that unless called by `erc-track-modified-channels', -;; `erc-track-faces-priority-list' will not begin with -;; `erc-track--attn-faces'. -(defun erc-track-select-mode-line-face (cur-face new-faces) - "Return the face to use in the mode line. - -CUR-FACE is the face currently used in the mode line (for the -current buffer). NEW-FACES is the list of new faces that have -just been seen (in the current buffer). - -Initially, the selected face is the one with highest priority in -`erc-track-faces-priority-list' (i.e., the one closest to the -front of the list) among CUR-FACE and NEW-FACES. If nothing -matches (including if `erc-track-faces-priority-list' is not -set), the default mode-line faces will be used (NIL is returned). - -If the selected face is still CUR-FACE (highest priority), and -the highest priority face in NEW-FACES alone is different (which -necessarily means it has lower priority than CUR-FACE), and both -are in `erc-track-faces-normal-list', then the latter is selected -instead. This has the effect of allowing the current mode line -face, if a member of `erc-track-faces-normal-list', to be -replaced with another with lower priority face from NEW-FACES, if -that face with highest priority in NEW-FACES is also a member of -`erc-track-faces-normal-list'. - -To put it another way, when CUR-FACE outranks all NEW-FACES and -doesn't appear among them, it's eligible to be replaced with a -fellow \"normal\" from NEW-FACES. But if it does appear among -them, it can't be replaced." - (let ((choice (catch 'face - (dolist (candidate erc-track-faces-priority-list) - (when (or (equal candidate cur-face) - (member candidate new-faces)) - (throw 'face candidate)))))) - (when choice - (if (and (equal choice cur-face) - (member choice erc-track-faces-normal-list)) - (let ((only-in-new - (catch 'face - (dolist (candidate erc-track-faces-priority-list) - (when (member candidate new-faces) - (throw 'face candidate)))))) - (if (member only-in-new erc-track-faces-normal-list) - only-in-new - choice)) - choice)))) - -(defvar erc-track--alt-normals-function nil - "A function to possibly elect a \"normal\" face. -Called with the current incumbent and the worthiest new contender -followed by all new contending faces, ranked faces, and so-called -\"normal\" faces. See `erc-track--select-mode-line-face' for their -meanings and expected types. This function should return a face or nil.") - -(defun erc-track--select-mode-line-face (cur-face new-faces ranks normals) - "Return CUR-FACE or a replacement for displaying in the mode-line, or nil. -Expect NEW-FACES to be a cons cell whose car is a hash table mapping -faces present in the applicable region to t and whose cdr is its car's -contents ordered from most recently seen (later in the buffer) to -earliest. Expect RANKS to be a cons cell whose car is a hash table -similar to `erc-track--priority-faces' and whose cdr is a list of -prioritized faces resembling `erc-track-faces-priority-list'. Expect -NORMALS to be a hash table mapping faces to themselves. In general, act -identically to `erc-track-select-mode-line-face', except appeal to -`erc-track--alt-normals-function' if it's non-nil, and fall back on -reconsidering only NEW-FACES appearing in NORMALS when CUR-FACE is -itself \"normal\" and outranks all NEW-FACES. That is, choose the first -among RANKS in both NEW-FACES and NORMALS not equal to CUR-FACE. -Failing that, choose the first face in both NEW-FACES and NORMALS." - (cl-check-type erc-track-ignore-normal-contenders-p null) - (cl-check-type new-faces cons) - ;; Choose the highest ranked face in `erc-track-faces-priority-list' - ;; that's either `cur-face' itself or one appearing in the region - ;; being processed. - (when-let ((choice (catch 'face - (dolist (candidate (cdr ranks)) - (when (or (equal candidate cur-face) - (gethash candidate (car new-faces))) - (throw 'face candidate)))))) - (or (and erc-track--alt-normals-function - (funcall erc-track--alt-normals-function - cur-face choice new-faces ranks normals)) - ;; If `choice' is still `cur-face' and also a "normal", attempt - ;; to choose another normal in order to produce the flickering - ;; effect mentioned in the doc of `erc-track-faces-normal-list'. - (and (equal choice cur-face) - (gethash choice normals) - (catch 'face - ;; If ranked "normal" faces other than `choice' appear in - ;; the region, return the most important one. - (progn - (dolist (candidate (cdr ranks)) - (when (and (not (equal candidate choice)) - (gethash candidate (car new-faces)) - (gethash choice normals)) - (throw 'face candidate))) - ;; Otherwise, go with any "normal" face other than - ;; `choice' in the region. - (dolist (candidate (cdr new-faces)) - (when (and (not (equal candidate choice)) - (gethash candidate normals)) - (throw 'face candidate)))))) - choice))) - -(defun erc-track-modified-channels () - "Hook function for `erc-insert-post-hook'. -Check if the current buffer should be added to the mode line as a -hidden, modified channel. Assumes it will only be called when -the 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 - ;; FIXME either use `erc--server-buffer-p' or - ;; explain why that's unwise. - (erc-server-or-unjoined-channel-buffer-p))) - (not (let ((parsed (erc-find-parsed-property))) - (or (erc-message-type-member (or parsed (point-min)) - erc-track-exclude-types) - ;; Skip certain non-server-sent messages. - (and (not parsed) - (erc--memq-msg-prop 'erc--skip 'track)))))) - ;; 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. - (when-let - ((faces (if erc-track-ignore-normal-contenders-p - (erc-faces-in (buffer-string)) - (erc-track--collect-faces-in))) - (normals erc-track--normal-faces) - (erc-track-faces-priority-list - `(,@erc-track--attn-faces ,@erc-track-faces-priority-list)) - (ranks (cons erc-track--priority-faces - erc-track-faces-priority-list)) - ((not (and - (or (eq erc-track-priority-faces-only 'all) - (member this-channel erc-track-priority-faces-only)) - ;; Iterate over the shorter of `ranks' and `faces'. - (let* ((r>fp (or erc-track-ignore-normal-contenders-p - (> (hash-table-count (car ranks)) - (hash-table-count (car faces))))) - (elems (cond ((not r>fp) (cdr ranks)) ; f>=r - (erc-track-ignore-normal-contenders-p - faces) - ((cdr faces)))) - (table (if r>fp (car ranks) (car faces)))) - (not (catch 'found - (dolist (f elems) - (when (gethash f table) - (throw 'found t)))))))))) - (progn ; FIXME remove `progn' on next major edit - (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 (if erc-track-ignore-normal-contenders-p - (erc-track-select-mode-line-face - nil faces) - (erc-track--select-mode-line-face - nil faces ranks normals)))) - erc-modified-channels-alist)) - ;; Else modify the face for the buffer, if necessary. - (when (or erc-track-ignore-normal-contenders-p (cdr faces)) - (let* ((cell (assq (current-buffer) - erc-modified-channels-alist)) - (old-face (cddr cell)) - (new-face (if erc-track-ignore-normal-contenders-p - (erc-track-select-mode-line-face - old-face faces) - (erc-track--select-mode-line-face - old-face faces ranks normals)))) - (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 (and (or (erc-buffer-visible (current-buffer)) - (and this-channel - (member this-channel erc-track-exclude))) - (assq (current-buffer) erc-modified-channels-alist)) - ;; 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 (let ((face1 (get-text-property 0 'face str))) - (when face1 (list face1)))) - cur) - (while (and (setq i (next-single-property-change i 'face str m)) - (not (= i m))) - (and (setq cur (get-text-property i 'face str)) - (not (member cur faces)) - (push cur faces))) - faces)) - -(defvar erc-track--face-reject-function nil - "Function called with face in current buffer to massage or reject.") - -(defun erc-track--collect-faces-in () - "Collect all faces in the (presumably narrowed) current buffer. -Return a cons cell of a hash table and a list ordered from most recently -seen to least." - (let* ((prop (if noninteractive 'font-lock-face 'face)) - (p (text-property-not-all (point-min) (point-max) prop nil)) - (seen (and p (make-hash-table :test #'equal))) - (faces (make-hash-table :test #'equal)) - (rfaces ())) - (while p - (when-let ((cur (get-text-property p prop))) - (unless (gethash cur seen) - (puthash cur t seen) - (when erc-track--face-reject-function - (setq cur (funcall erc-track--face-reject-function cur))) - (when cur - (push cur rfaces) - (puthash cur t faces)))) - (setq p (next-single-property-change p prop))) - (cons faces rfaces))) - -;;; Buffer switching - -(defvar erc-track-last-non-erc-buffer nil - "Name of the last buffer before activating `erc-track-switch-buffer'.") - -(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-face-priority (face) - "Return priority (a number) of FACE in `erc-track-faces-priority-list'. -Lower number means higher priority. - -If face is not in `erc-track-faces-priority-list', it will have a -higher number than any other face in that list." - (let ((count 0)) - (catch 'done - (dolist (item `(,@erc-track--attn-faces ,@erc-track-faces-priority-list)) - (if (equal item face) - (throw 'done t) - (setq count (1+ count))))) - count)) - -(defun erc-track-sort-by-importance () - "Sort `erc-modified-channels-alist' by importance. -That means the position of the face in `erc-track-faces-priority-list'." - (setq erc-modified-channels-alist - (sort erc-modified-channels-alist - (lambda (a b) (< (erc-track-face-priority (cddr a)) - (erc-track-face-priority (cddr 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 (pcase dir - ('oldest 'newest) - ('newest 'oldest) - ('mostactive 'leastactive) - ('leastactive 'mostactive) - ('importance 'oldest))) - (setq arg (- arg))) - (setq offset (pcase dir - ((or 'oldest 'leastactive) - (- (length erc-modified-channels-alist) arg)) - (_ (1- arg)))) - ;; normalize 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)))) - -(defvar erc-track--switch-fallback-blockers '((derived-mode . erc-mode)) - "List of `buffer-match-p' conditions OR'd together. -ERC sets `erc-track-last-non-erc-buffer' to the current buffer -unless any passes.") - -(defun erc-track--switch-buffer (fun arg) - (if (not erc-track-mode) - (message (concat "Enable the ERC track module if you want to use the" - " tracking minor mode")) - (cond (erc-modified-channels-alist - ;; if we're not in erc-mode, set this buffer to return to - (unless (buffer-match-p (cons 'or - erc-track--switch-fallback-blockers) - (current-buffer)) - (setq erc-track-last-non-erc-buffer (current-buffer))) - ;; and jump to the next active channel - (if-let ((buf (erc-track-get-active-buffer arg)) - ((buffer-live-p buf))) - (funcall fun buf) - (erc-modified-channels-update) - (erc-track--switch-buffer fun 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)) - (funcall fun erc-track-last-non-erc-buffer))))) - -(defun erc-track-switch-buffer (arg) - "Switch to the next active ERC buffer. -If there are no active ERC buffers, switch back to the last -non-ERC buffer visited. The order of buffers is defined by -`erc-track-switch-direction', and a negative argument will -reverse it." - (interactive "p") - (erc-track--switch-buffer 'switch-to-buffer arg)) - -(defun erc-track-switch-buffer-other-window (arg) - "Switch to the next active ERC buffer in another window. -If there are no active ERC buffers, switch back to the last -non-ERC buffer visited. The order of buffers is defined by -`erc-track-switch-direction', and a negative argument will -reverse it." - (interactive "p") - (erc-track--switch-buffer 'switch-to-buffer-other-window arg)) - -(defun erc-track--replace-killed-buffer (existing) - (when-let ((found (assq existing erc-modified-channels-alist))) - (setcar found (current-buffer)))) - -(provide 'erc-track) - -;;; erc-track.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-truncate.el b/lisp/erc/erc-truncate.el deleted file mode 100644 index 26af46f7481..00000000000 --- a/lisp/erc/erc-truncate.el +++ /dev/null @@ -1,183 +0,0 @@ -;;; erc-truncate.el --- Functions for truncating ERC buffers -*- lexical-binding: t; -*- - -;; Copyright (C) 2003-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Andreas Fuchs -;; Maintainer: Amin Bandali , F. Jason Park -;; URL: https://www.emacswiki.org/emacs/ErcTruncation -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file implements buffer truncation through the `truncate' -;; module, with optional `log' module integration. - -;;; Code: - -(require 'erc) - -(defgroup erc-truncate nil - "Truncate buffers when they reach a certain size." - :group 'erc) - -(defcustom erc-max-buffer-size 30000 - "Buffer size in characters after truncation. -Only applies when the `truncate' module is enabled." - :type 'integer) - -(defcustom erc-truncate-padding-size 4096 - "Headroom threshold triggering truncation and determining its frequency. -Truncation occurs when the buffer's size meets or exceeds this value -plus `erc-max-buffer-size'." - :type 'integer - :package-version '(ERC . "5.6.1")) - -;;;###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. - -Before ERC 5.6, this module performed logging whenever the \\+`log' -module's library, \\+`erc-log', happened to be loaded, regardless of -whether the \\+`log' module itself was enabled. (Loading can of course -happen in any number of ways, such as when browsing options via -\\[customize-group] or completing autoloaded symbol names at the -\\[describe-variable] prompt.) Users of \\+`truncate' who prefer the -old behavior can add \\+`log' to `erc-modules' to get the same effect. -Those who don't want logging but need to load the \\+`erc-log' library -for other purposes should customize either `erc-enable-logging' or -`erc-log-channels-directory' to avoid the annoying warning." - ;;enable - ((add-hook 'erc-insert-done-hook #'erc-truncate-buffer) - (add-hook 'erc-connect-pre-hook #'erc-truncate--warn-about-logging) - (add-hook 'erc-mode-hook #'erc-truncate--setup) - (unless erc--updating-modules-p (erc-buffer-do #'erc-truncate--setup))) - ;; disable - ((remove-hook 'erc-insert-done-hook #'erc-truncate-buffer) - (remove-hook 'erc-connect-pre-hook #'erc-truncate--warn-about-logging) - (remove-hook 'erc-mode-hook #'erc-truncate--setup) - (erc-buffer-do #'erc-truncate--setup))) - -(defvar-local erc-truncate--buffer-size nil - "Temporary buffer-local override for `erc-max-buffer-size'.") - -(defun erc-truncate--setup () - "Enable or disable buffer-local `erc-truncate-mode' modifications." - (if erc-truncate-mode - (progn - (when-let ((priors (or erc--server-reconnecting erc--target-priors)) - (val (alist-get 'erc-truncate--buffer-size priors))) - (setq erc-truncate--buffer-size val)) - (add-function :before (local 'erc--clear-function) - #'erc-truncate--inhibit-when-local-and-interactive - '((depth . 20)))) - (remove-function (local 'erc--clear-function) - #'erc-truncate--inhibit-when-local-and-interactive) - (kill-local-variable 'erc-truncate--buffer-size))) - -(defun erc-truncate--warn-about-logging (&rest _) - (when (and (not erc--target) - (fboundp 'erc-log--check-legacy-implicit-enabling-by-truncate) - (erc-log--check-legacy-implicit-enabling-by-truncate)) - ;; Emit a real Emacs warning because the message may be - ;; truncated away before it can be read if merely inserted. - (erc-button--display-error-notice-with-keys-and-warn - "The `truncate' module no longer enables logging implicitly." - " See the doc string for `erc-truncate-mode' for details."))) - -;;;###autoload -(defun erc-truncate-buffer-to-size (size &optional buffer) - "Truncate BUFFER or the current buffer to SIZE. -Log the deleted region when the `log' module is active and -`erc-logging-enabled' returns non-nil. - -Note that prior to ERC 5.6, whenever erc-log.el happened to be -loaded and the option `erc-enable-logging' was left at its -default value, this function would cause logging to commence -regardless of whether `erc-log-mode' was enabled or `log' was -present in `erc-modules'." - ;; 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 (and (> (buffer-size buffer) (+ size erc-truncate-padding-size)) - (not (buffer-local-value 'erc--inhibit-clear-p buffer))) - (with-current-buffer buffer - (let ((wc (and (get-buffer-window) (current-window-configuration)))) - (save-excursion - ;; Widen to preserve pre-5.5 behavior. - (save-restriction - (widen) - (let ((beg (point-min-marker)) - (end (goto-char (- erc-insert-marker size)))) - ;; Truncate at message boundary (formerly line boundary - ;; before 5.6). - (goto-char (or (erc--get-inserted-msg-beg end) (pos-bol))) - (setq end (point-marker)) - (with-silent-modifications - (let ((erc--inhibit-clear-p t)) - (funcall erc--clear-function beg end))) - (set-marker beg nil) - (set-marker end nil)))) - (when wc - (set-window-configuration wc)))))) - -;;;###autoload -(defun erc-truncate-buffer () - "Truncate current buffer to `erc-max-buffer-size'." - (interactive) - ;; This `save-excursion' only exists for historical reasons because - ;; `erc-truncate-buffer-to-size' normally runs in a different buffer. - (save-excursion - (if (and erc--parsed-response erc--msg-props) - (when-let - (((not erc--inhibit-clear-p)) - ((not (erc--memq-msg-prop 'erc--skip 'truncate))) - ;; Determine here because this may be a target buffer and - ;; the hook always runs in the server buffer. - (size (if (and erc-truncate--buffer-size - (> erc-truncate--buffer-size erc-max-buffer-size)) - erc-truncate--buffer-size - erc-max-buffer-size)) - (symbol (make-symbol "erc-truncate--buffer-deferred")) - (buffer (current-buffer))) - (fset symbol - (lambda (&rest _) - (remove-hook 'erc-timer-hook symbol t) - (erc-truncate-buffer-to-size size buffer))) - (erc-with-server-buffer (add-hook 'erc-timer-hook symbol -80 t))) - (unless erc--inhibit-clear-p - (erc-truncate-buffer-to-size erc-max-buffer-size))))) - -(defun erc-truncate--inhibit-when-local-and-interactive (&rest _) - "Ensure `erc-truncate--buffer-size' is nil on /CLEAR." - (when (and erc--called-as-input-p erc-truncate--buffer-size) - (message "Resetting max buffer size to %d" erc-max-buffer-size) - (setq erc-truncate--buffer-size nil))) - -(provide 'erc-truncate) -;;; erc-truncate.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc-xdcc.el b/lisp/erc/erc-xdcc.el deleted file mode 100644 index 35b2ece006b..00000000000 --- a/lisp/erc/erc-xdcc.el +++ /dev/null @@ -1,137 +0,0 @@ -;;; erc-xdcc.el --- XDCC file-server support for ERC -*- lexical-binding: t; -*- - -;; Copyright (C) 2003-2004, 2006-2025 Free Software Foundation, Inc. - -;; Author: Mario Lang -;; Maintainer: Amin Bandali , F. Jason Park -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; This file provides a very simple XDCC file server for ERC. - -;;; 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 strings." - :group 'erc-dcc - :type '(repeat (repeat :tag "Message" (choice string sexp)))) - -;;;###autoload(autoload 'erc-xdcc-mode "erc-xdcc") -(define-erc-module xdcc nil - "Act as an XDCC file-server." - nil nil) - -;;;###autoload -(defun erc-xdcc-add-file (file) - "Add 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 t))) 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) - -;;; erc-xdcc.el ends here -;; -;; Local Variables: -;; generated-autoload-file: "erc-loaddefs.el" -;; End: diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el deleted file mode 100644 index a661ae0a3a9..00000000000 --- a/lisp/erc/erc.el +++ /dev/null @@ -1,9908 +0,0 @@ -;;; erc.el --- An Emacs Internet Relay Chat client -*- lexical-binding:t -*- - -;; Copyright (C) 1997-2025 Free Software Foundation, Inc. - -;; Author: Alexander L. Belikoff -;; Maintainer: Amin Bandali , F. Jason Park -;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu), -;; Mario Lang (mlang@delysid.org), -;; Alex Schroeder (alex@gnu.org) -;; Andreas Fuchs (afs@void.at) -;; Gergely Nagy (algernon@midgard.debian.net) -;; David Edmondson (dme@dme.org) -;; Michael Olson (mwolson@gnu.org) -;; Kelvin White (kwhite@gnu.org) -;; Version: 5.6.1-git -;; Package-Requires: ((emacs "27.1") (compat "29.1.4.5")) -;; Keywords: IRC, chat, client, Internet -;; URL: https://www.gnu.org/software/emacs/erc.html - -;; This is a GNU ELPA :core package. Avoid functionality that is not -;; compatible with the version of Emacs recorded above. - -;; 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 3 of the License, 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. If not, see . - -;;; Commentary: - -;; ERC is a powerful, modular, and extensible IRC client for Emacs. -;; For more information, visit the ERC page at -;; . - -;; Configuration: - -;; Use M-x customize-group RET erc RET to get an overview -;; of all the variables you can tweak. - -;; Usage: - -;; To connect to an IRC server, do -;; -;; M-x erc RET -;; -;; or -;; -;; M-x erc-tls RET -;; -;; to connect over TLS (encrypted). Once you are connected to a -;; server, you can use C-h m or have a look at the ERC menu. - -;;; Code: - -(eval-and-compile (load "erc-loaddefs" 'noerror 'nomessage)) - -(require 'erc-networks) -(require 'erc-backend) -(require 'cl-lib) -(require 'format-spec) -(require 'auth-source) -(eval-when-compile (require 'subr-x)) - -(defconst erc-version "5.6.1-git" - "This version of ERC.") - -(defvar erc-official-location - "https://www.gnu.org/software/emacs/erc.html (mailing list: emacs-erc@gnu.org)" - "Location of the ERC client on the Internet.") - -;; Map each :package-version to the associated Emacs version. -;; (This eliminates the need for explicit :version keywords on the -;; custom definitions.) -(add-to-list - 'customize-package-emacs-version-alist - '(ERC ("5.2" . "22.1") - ("5.3" . "23.1") - ("5.4" . "28.1") - ("5.4.1" . "29.1") - ("5.5" . "29.1") - ("5.6" . "30.1") - ("5.6.1" . "31.1"))) - -(defgroup erc nil - "Emacs Internet Relay Chat client." - :link '(url-link "https://www.gnu.org/software/emacs/erc.html") - :link '(custom-manual "(erc) Top") - :prefix "erc-" - :group 'applications) - -(defgroup erc-buffers nil - "Creating new ERC buffers." - :group 'erc) - -(defgroup erc-display nil - "Settings controlling how various things are displayed. -See the customization group `erc-buffers' for display options -concerning buffers." - :group 'erc) - -(defgroup erc-mode-line-and-header nil - "Displaying information in the mode-line and header." - :group 'erc-display) - -(defgroup erc-ignore nil - "Ignoring certain messages." - :group 'erc) - -(defgroup erc-lurker nil - "Hide specified message types sent by lurkers." - :version "24.3" - :group 'erc-ignore) - -(defgroup erc-query nil - "Using separate buffers for private discussions." - :group 'erc) - -(defgroup erc-quit-and-part nil - "Quitting and parting channels." - :group 'erc) - -(defgroup erc-paranoia nil - "Know what is sent and received; control the display of sensitive data." - :group 'erc) - -(defgroup erc-scripts nil - "Running scripts at startup and with /LOAD." - :group 'erc) - -;; Add `custom-loads' features for group symbols missing from a -;; supported Emacs version, possibly because they belong to a new ERC -;; library. These groups all share their library's feature name. -;;;###autoload(dolist (symbol '( erc-sasl erc-spelling ; 29 -;;;###autoload erc-imenu erc-nicks)) ; 30 -;;;###autoload (custom-add-load symbol symbol)) - -(defvar erc-message-parsed) ; only known to this file - -(defvar erc--msg-props nil - "Hash table containing metadata properties for current message. -Provided by the insertion functions `erc-display-message' and -`erc-display-msg' while running their modification hooks. -Initialized when null for each visitation round from function -parameters and environmental factors, as well as the alist -`erc--msg-prop-overrides'. Keys are symbols. Values are opaque -objects, unless otherwise specified. Items present after running -`erc-insert-post-hook' or `erc-send-post-hook' become text -properties added to the first character of an inserted message. -A given message therefore spans the interval extending from one -set of such properties to the newline before the next (or -`erc-insert-marker'). As of ERC 5.6, this forms the basis for -visiting and editing inserted messages. Modules should align -their markers accordingly. The following properties have meaning -as of ERC 5.6: - - - `erc--msg': a symbol, guaranteed present; possible values - include `unknown', a fallback used by `erc-display-message'; a - catalog key, such as `s401' or `finished'; an - `erc-display-message' TYPE parameter, like `notice' - - - `erc--cmd': a message's associated IRC command, as read by - `erc--get-eq-comparable-cmd'; currently either a symbol, like - `PRIVMSG', or a number, like 5, which represents the numeric - \"005\"; absent on \"local\" messages, such as simple warnings - and help text, and on outgoing messages unless echoed back by - the server (assuming future support) - - - `erc--spkr': a string, the non-case-mapped nick of the speaker as - stored in the `nickname' slot of its `erc-server-users' item - - - `erc--ctcp': a CTCP command, like `ACTION' - - - `erc--ts': a timestamp, possibly provided by the server; as of - 5.6, a ticks/hertz pair on Emacs 29 and above, and a \"list\" - type otherwise; managed by the `stamp' module - - - `erc--skip': list of symbols known to modules that indicate an - intent to skip or simplify module-specific processing - - - `erc--ephemeral': a symbol prefixed by or matching a module - name; indicates to other modules and members of modification - hooks that the current message should not affect stateful - operations, such as recording a channel's most recent speaker - - - `erc--hide': a symbol or list of symbols added as an `invisible' - prop value to the entire message, starting *before* the preceding - newline and ending before the trailing newline - -This is an internal API, and the selection of related helper -utilities is fluid and provisional. As of ERC 5.6, see the -functions `erc--check-msg-prop' and `erc--get-inserted-msg-prop'.") - -(defvar erc--msg-prop-overrides nil - "Alist of \"message properties\" for populating `erc--msg-props'. -These override any defaults normally shown to modification hooks -by `erc-display-msg' and `erc-display-message'. Modules should -accommodate existing overrides when applicable. Items toward the -front shadow any that follow. Ignored when `erc--msg-props' is -already non-nil.") - -;; Forward declarations -(declare-function decoded-time-period "time-date" (time)) -(declare-function iso8601-parse-duration "iso8601" (string)) -(declare-function word-at-point "thingatpt" (&optional no-properties)) -(autoload 'word-at-point "thingatpt") ; for hl-nicks - -(declare-function gnutls-negotiate "gnutls" (&rest rest)) -(declare-function socks-open-network-stream "socks" (name buffer host service)) -(declare-function url-host "url-parse" (cl-x)) -(declare-function url-password "url-parse" (cl-x)) -(declare-function url-portspec "url-parse" (cl-x)) -(declare-function url-type "url-parse" (cl-x)) -(declare-function url-user "url-parse" (cl-x)) - -;; tunable connection and authentication parameters - -(defcustom erc-server nil - "IRC server to use if one is not provided. -See function `erc-compute-server' for more details on connection -parameters and authentication." - :group 'erc - :type '(choice (const :tag "None" nil) - (string :tag "Server"))) - -(defcustom erc-port nil - "IRC port to use if not specified. - -This can be either a string or a number." - :group 'erc - :type '(choice (const :tag "None" nil) - (integer :tag "Port number") - (string :tag "Port string"))) - -(defcustom erc-nick nil - "Nickname to use if one is not provided. - -This can be either a string, or a list of strings. -In the latter case, if the first nick in the list is already in use, -other nicks are tried in the list order. - -See function `erc-compute-nick' for more details on connection -parameters and authentication." - :group 'erc - :type '(choice (const :tag "None" nil) - (string :tag "Nickname") - (repeat (string :tag "Nickname")))) - -(defcustom erc-nick-uniquifier "`" - "The string to append to the nick if it is already in use." - :group 'erc - :type 'string) - -(defcustom erc-try-new-nick-p t - "Non-nil means attempt to connect with another nickname if nickname unavailable. -You can manually set another nickname with the /NICK command." - :group 'erc - :type 'boolean) - -(defcustom erc-user-full-name nil - "User full name. - -This can be either a string or a function to call. - -See function `erc-compute-full-name' for more details on connection -parameters and authentication." - :group 'erc - :type '(choice (const :tag "No name" nil) - (string :tag "Name") - (function :tag "Get from function")) - :set (lambda (sym val) - (set sym (if (functionp val) (funcall val) val)))) - -(defcustom erc-rename-buffers t - "Non-nil means rename buffers with network name, if available." - :version "24.5" - :group 'erc - :type 'boolean) - -;; For the sake of compatibility, an ID will be created on the user's -;; behalf when `erc-rename-buffers' is nil and one wasn't provided. -;; The name will simply be that of the buffer, usually SERVER:PORT. -;; This violates the policy of treating provided IDs as gospel, but -;; it'll have to do for now. - -(make-obsolete-variable 'erc-rename-buffers - "old behavior when t now permanent" "29.1") - -(defvar erc-password nil - "Password to use when authenticating to an IRC server interactively. - -This variable only exists for legacy reasons. It's not customizable and -is limited to a single server password. Users looking for similar -functionality should consider auth-source instead. See Info -node `(auth) Top' and Info node `(erc) auth-source'.") - -(make-obsolete-variable 'erc-password "use auth-source instead" "29.1") - -(defcustom erc-user-mode "+i" - ;; +i "Invisible". Hides user from global /who and /names. - "Initial user modes to be set after a connection is established." - :group 'erc - :type '(choice (const nil) string function) - :version "28.1") - - -(defcustom erc-prompt-for-password t - "Ask for a server password when invoking `erc-tls' interactively." - :group 'erc - :type 'boolean) - -(defcustom erc-warn-about-blank-lines t - "Warn the user if they attempt to send a blank line. -When non-nil, ERC signals a `user-error' upon encountering prompt -input containing empty or whitespace-only lines. When nil, ERC -still inhibits sending but does so silently. With the companion -option `erc-send-whitespace-lines' enabled, ERC sends pending -input and prints a message in the echo area indicating the amount -of padding and/or stripping applied, if any. Setting this option -to nil suppresses such reporting." - :group 'erc - :type 'boolean) - -(defcustom erc-send-whitespace-lines nil - "If set to non-nil, send lines consisting of only whitespace." - :group 'erc - :type 'boolean) - -(defcustom erc-inhibit-multiline-input nil - "When non-nil, conditionally disallow input consisting of multiple lines. -Issue an error when the number of input lines submitted for -sending meets or exceeds this value. The value t is synonymous -with a value of 2 and means disallow more than 1 line of input." - :package-version '(ERC . "5.5") - :group 'erc - :type '(choice integer boolean)) - -(defcustom erc-ask-about-multiline-input nil - "Whether to ask to ignore `erc-inhibit-multiline-input' when tripped." - :package-version '(ERC . "5.5") - :group 'erc - :type 'boolean) - -(defcustom erc-prompt-hidden ">" - "Text to show in lieu of the prompt when hidden." - :package-version '(ERC . "5.5") - :group 'erc-display - :type 'string) - -(defcustom erc-hide-prompt t - "If non-nil, hide input prompt upon disconnecting. -To unhide, type something in the input area. Once revealed, a -prompt remains unhidden until the next disconnection. Channel -prompts are unhidden upon rejoining. For behavior concerning -query prompts, see `erc-unhide-query-prompt'. Longtime ERC users -should note that this option was repurposed in ERC 5.5 because it -had lain dormant for years after being sidelined in 5.3 when its -only use in the interactive client was removed. Before then, its -role was controlling whether `erc-command-indicator' would appear -alongside echoed slash-command lines." - :package-version '(ERC . "5.5") - :group 'erc-display - :type '(choice (const :tag "Always hide prompt" t) - (set (const server) - (const query) - (const channel)))) - -(defcustom erc-unhide-query-prompt nil - "When non-nil, always reveal query prompts upon reconnecting. -Otherwise, prompts in a connection's query buffers remain hidden -until the user types in the input area or a new message arrives -from the target." - :package-version '(ERC . "5.5") - :group 'erc-display - ;; Extensions may one day offer a way to discover whether a target - ;; is online. When that happens, this can be expanded accordingly. - :type 'boolean) - -;; tunable GUI stuff - -(defcustom erc-show-my-nick t - "If non-nil, display one's own nickname when sending a message. - -If non-nil, \"\" will be shown. -If nil, only \"> \" will be shown." - :group 'erc-display - :type 'boolean) - -(define-widget 'erc-message-type 'set - "A set of standard IRC Message types." - :args '((const "JOIN") - (const "KICK") - (const "NICK") - (const "PART") - (const "QUIT") - (const "MODE") - (const :tag "Away notices (RPL_AWAY 301)" "301") - (const :tag "Self back notice (REP_UNAWAY 305)" "305") - (const :tag "Self away notice (REP_NOWAWAY 306)" "306") - (const :tag "Channel modes on join (RPL_CHANNELMODEIS 324)" "324") - (const :tag "Channel creation time (RPL_CREATIONTIME 329)" "329") - (const :tag "Channel no-topic on join (RPL_NOTOPIC 331)" "331") - (const :tag "Channel topic on join (RPL_TOPIC 332)" "332") - (const :tag "Topic author and time on join (RPL_TOPICWHOTIME 333)" "333") - (const :tag "Invitation success notice (RPL_INVITING 341)" "341") - (const :tag "Channel member names (353 RPL_NAMEREPLY)" "353") - (repeat :inline t :tag "Others" (string :tag "IRC Message Type")))) - -(defcustom erc-hide-list nil - "A global list of IRC message types to hide. -A typical value would be \(\"JOIN\" \"PART\" \"QUIT\")." - :group 'erc-ignore - :type 'erc-message-type) - -(defcustom erc-network-hide-list nil - "A list of IRC networks to hide message types from. -A typical value would be \((\"Libera.Chat\" \"MODE\") - \(\"OFTC\" \"JOIN\" \"QUIT\"))." - :version "25.1" - :group 'erc-ignore - :type '(alist :key-type string :value-type erc-message-type - :options ("Libera.Chat"))) - -(defcustom erc-channel-hide-list nil - "A list of IRC channels to hide message types from. -A typical value would be \((\"#emacs\" \"QUIT\" \"JOIN\") - \(\"#erc\" \"NICK\")." - :version "25.1" - :group 'erc-ignore - :type '(alist :key-type string :value-type erc-message-type - :options ("#emacs"))) - -(defcustom erc-disconnected-hook nil - "Run this hook with arguments (NICK IP REASON) when disconnected. -This happens before automatic reconnection. Note, that -`erc-server-QUIT-functions' might not be run when we disconnect, -simply because we do not necessarily receive the QUIT event." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-complete-functions nil - "These functions get called when the user hits \\`TAB' in ERC. -Each function in turn is called until one returns non-nil to -indicate it has handled the input." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-join-hook nil - "Hook run when we join a channel. -Hook functions are called without arguments, with the current -buffer set to the buffer of the new channel. - -See also `erc-server-JOIN-functions', `erc-part-hook'." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-quit-hook nil - "Hook run when processing a quit command directed at our nick. - -The hook receives one argument, the current PROCESS. -See also `erc-server-QUIT-functions' and `erc-disconnected-hook'." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-part-hook nil - "Hook run when processing a PART message directed at our nick. -Called in the server buffer with a single argument: the channel buffer -being parted. For historical reasons, the buffer argument may be nil if -it's been killed or otherwise can't be found. This typically happens -when the \"PART\" response being handled comes by way of a channel -buffer being killed, which, by default, tells `erc-part-channel-on-kill' -to emit a \"PART\". Users needing to operate on a parted channel buffer -before it's killed in this manner should use `erc-kill-channel-hook' and -condition their code on `erc-killing-buffer-on-part-p' being nil." - :group 'erc-hooks - :type 'hook) - -(defvar erc-killing-buffer-on-part-p nil - "Non-nil when killing a target buffer while handling a \"PART\" response. -Useful for preventing the redundant execution of code designed to run -once when parting a channel.") - -(defcustom erc-kick-hook nil - "Hook run when processing a KICK message directed at our nick. - -The hook receives one argument, the current BUFFER. -See also `erc-server-PART-functions' and `erc-part-hook'." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-nick-changed-functions nil - "List of functions run when your nick was successfully changed. - -Each function should accept two arguments, NEW-NICK and OLD-NICK." - :group 'erc-hooks - :type 'hook) - -(defcustom erc-connect-pre-hook '(erc-initialize-log-marker) - "Hook called just before `erc' calls `erc-connect'. -Functions are passed a buffer as the first argument." - :group 'erc-hooks - :type 'hook) - -(defvaralias 'erc-channel-users 'erc-channel-members) -(defvar-local erc-channel-members nil - "Hash table of members in the current channel or query buffer. -It associates nicknames with cons cells of the form -\(SERVER-USER . MEMBER-DATA), where SERVER-USER is a -`erc-server-user' object and MEMBER-DATA is a `erc-channel-user' -object. Convenient abbreviations for these two components are -`susr' and `cusr', along with `cmem' for the pair.") - -(defvar-local erc-server-users nil - "Hash table of users on the current server. -It associates nicknames with `erc-server-user' struct instances.") - -(defconst erc--casemapping-rfc1459-strict - (let ((tbl (copy-sequence ascii-case-table)) - (cup (copy-sequence (char-table-extra-slot ascii-case-table 0)))) - (set-char-table-extra-slot tbl 0 cup) - (set-char-table-extra-slot tbl 1 nil) - (set-char-table-extra-slot tbl 2 nil) - (pcase-dolist (`(,uc . ,lc) '((?\[ . ?\{) (?\] . ?\}) (?\\ . ?\|))) - (aset tbl uc lc) - (aset tbl lc lc) - (aset cup uc uc)) - tbl)) - -(defconst erc--casemapping-rfc1459 - (let ((tbl (copy-sequence erc--casemapping-rfc1459-strict)) - (cup (copy-sequence (char-table-extra-slot - erc--casemapping-rfc1459-strict 0)))) - (set-char-table-extra-slot tbl 0 cup) - (aset tbl ?~ ?^) - (aset tbl ?^ ?^) - (aset cup ?~ ?~) - tbl)) - -(defun erc-add-server-user (nick user) - "This function is for internal use only. - -Adds USER with nickname NICK to the `erc-server-users' hash table." - (erc-with-server-buffer - (puthash (erc-downcase nick) user erc-server-users))) - -(defvar erc--decouple-query-and-channel-membership-p nil - "When non-nil, don't tether query participation to channel membership. -Specifically, add users to query tables when they speak, don't remove -them when they leave all channels, and allow removing the client's own -user from `erc-server-users'. Note that enabling this compatibility -flag degrades the user experience and isn't guaranteed to correctly -restore the described historical behavior.") - -(cl-defmethod erc--queries-current-p () - "Return non-nil if ERC actively updates query manifests." - (and (not erc--decouple-query-and-channel-membership-p) - (erc-query-buffer-p) (erc-get-channel-member (erc-target)))) - -(defun erc--ensure-query-member (nick) - "Populate membership table in query buffer for online NICK." - (erc-with-buffer (nick) - (when-let (((not erc--decouple-query-and-channel-membership-p)) - ((zerop (hash-table-count erc-channel-users))) - (user (erc-get-server-user nick))) - (erc-update-current-channel-member nick nil t) - (erc--unhide-prompt) - t))) - -(defun erc--ensure-query-members () - "Update membership tables in all query buffers. -Ensure targets with an entry in `erc-server-users' are present in -`erc-channel-members'." - (erc-with-all-buffers-of-server erc-server-process #'erc-query-buffer-p - (when-let (((not erc--decouple-query-and-channel-membership-p)) - ((zerop (hash-table-count erc-channel-users))) - (target (erc-target)) - ((erc-get-server-user target))) - (erc-update-current-channel-member target nil t) - (erc--unhide-prompt)) - erc-server-process)) - -(defun erc-remove-server-user (nick) - "Remove NICK from the session's `erc-server-users' table." - (erc-with-server-buffer - (remhash (erc-downcase nick) erc-server-users))) - -(defun erc-change-user-nickname (user new-nick) - "This function is for internal use only. - -Changes the nickname of USER to NEW-NICK in the -`erc-server-users' hash table. The `erc-channel-users' lists of -other buffers are also changed." - (let ((nick (erc-server-user-nickname user))) - (setf (erc-server-user-nickname user) new-nick) - (erc-with-server-buffer - (remhash (erc-downcase nick) erc-server-users) - (puthash (erc-downcase new-nick) user erc-server-users)) - (dolist (buf (erc-server-user-buffers user)) - (if (buffer-live-p buf) - (with-current-buffer buf - (let ((cdata (erc-get-channel-user nick))) - (remhash (erc-downcase nick) erc-channel-users) - (puthash (erc-downcase new-nick) cdata - erc-channel-users))))))) - -(defvar erc--forget-server-user-function - #'erc--forget-server-user-ignoring-queries - "Function to conditionally remove a user from `erc-server-users'. -Called with a nick and its `erc-server-user' object.") - -(defun erc--forget-server-user (nick user) - "Remove NICK's USER from server table if they're not in any target buffers." - (unless (erc-server-user-buffers user) - (erc-remove-server-user nick))) - -(defun erc--forget-server-user-ignoring-queries (nick user) - "Remove NICK's USER from `erc-server-users' if they've parted all channels." - (let ((buffers (erc-server-user-buffers user))) - (when (or (null buffers) - (and (not erc--decouple-query-and-channel-membership-p) - (cl-every #'erc-query-buffer-p buffers))) - (when buffers - (erc--remove-user-from-targets (erc-downcase nick) buffers)) - (erc-remove-server-user nick)))) - -(defun erc-remove-channel-user (nick) - "Remove NICK from the current target buffer's `erc-channel-members'. -If this was their only target, also remove them from `erc-server-users'." - (let ((channel-data (erc-get-channel-user nick))) - (when channel-data - (let ((user (car channel-data))) - (setf (erc-server-user-buffers user) - (delq (current-buffer) - (erc-server-user-buffers user))) - (remhash (erc-downcase nick) erc-channel-users) - (funcall erc--forget-server-user-function nick user))))) - -(defun erc-remove-user (nick) - "Remove NICK from the server and all relevant channels tables." - (let ((user (erc-get-server-user nick))) - (when user - (erc--remove-user-from-targets (erc-downcase nick) - (erc-server-user-buffers user)) - (erc-remove-server-user nick)))) - -(defun erc-remove-channel-users () - "Drain current buffer's `erc-channel-members' table. -Also remove members from the server table if this was their only buffer." - (when (erc--target-channel-p erc--target) - (setf (erc--target-channel-joined-p erc--target) nil)) - (when (and erc-server-connected - (erc-server-process-alive) - (hash-table-p erc-channel-users)) - (maphash (lambda (nick _cdata) - (erc-remove-channel-user nick)) - erc-channel-users) - (clrhash erc-channel-users))) - -(defun erc--remove-channel-users-but (nick) - "Drain channel users and remove from server, sparing NICK." - (when-let ((users (erc-with-server-buffer erc-server-users)) - (my-user (gethash (erc-downcase nick) users)) - (original-function erc--forget-server-user-function) - (erc--forget-server-user-function - (if erc--decouple-query-and-channel-membership-p - erc--forget-server-user-function - (lambda (nick user) - (unless (eq user my-user) - (funcall original-function nick user)))))) - (erc-remove-channel-users))) - -(defmacro erc--define-channel-user-status-compat-getter (name c d) - "Define accessor with gv getter for historical `erc-channel-user' slot NAME. -Expect NAME to be a string, C to be its traditionally associated letter, -and D to be its fallback power-of-2 integer for non-ERC buffers. Unlike -pre-ERC-5.6 accessors, do not bother generating a compiler macro for -inlining calls to these adapters." - `(defun ,(intern (concat "erc-channel-user-" name)) (u) - ,(format "Get equivalent of pre-5.6 `%s' slot for `erc-channel-user'." - name) - (declare (gv-setter (lambda (v) - (macroexp-let2 nil v v - (,'\`(let ((val (erc-channel-user-status ,',u)) - (n (or (erc--get-prefix-flag ,c) ,d))) - (setf (erc-channel-user-status ,',u) - (if ,',v - (logior val n) - (logand val (lognot n)))) - ,',v)))))) - (let ((n (or (erc--get-prefix-flag ,c) ,d))) - (= n (logand n (erc-channel-user-status u)))))) - -(erc--define-channel-user-status-compat-getter "voice" ?v 1) -(erc--define-channel-user-status-compat-getter "halfop" ?h 2) -(erc--define-channel-user-status-compat-getter "op" ?o 4) -(erc--define-channel-user-status-compat-getter "admin" ?a 8) -(erc--define-channel-user-status-compat-getter "owner" ?q 16) - -;; This is a generalized version of the compat-oriented getters above. -(defun erc--cusr-status-p (nick-or-cusr letter) - "Return non-nil if NICK-OR-CUSR has channel membership status LETTER." - (and-let* ((cusr (or (and (erc-channel-user-p nick-or-cusr) nick-or-cusr) - (cdr (erc-get-channel-member nick-or-cusr)))) - (n (erc--get-prefix-flag letter))) - (= n (logand n (erc-channel-user-status cusr))))) - -(defun erc--cusr-change-status (nick-or-cusr letter enablep &optional resetp) - "Add or remove membership status associated with LETTER for NICK-OR-CUSR. -With RESETP, clear the user's status info completely. If ENABLEP -is non-nil, add the status value associated with LETTER." - (when-let ((cusr (or (and (erc-channel-user-p nick-or-cusr) nick-or-cusr) - (cdr (erc-get-channel-member nick-or-cusr)))) - (n (erc--get-prefix-flag letter))) - (cl-callf (lambda (v) - (if resetp - (if enablep n 0) - (if enablep (logior v n) (logand v (lognot n))))) - (erc-channel-user-status cusr)))) - -(defun erc-channel-user-owner-p (nick) - "Return non-nil if NICK is an owner of the current channel." - (and nick - (hash-table-p erc-channel-users) - (let ((cdata (erc-get-channel-user nick))) - (and cdata (cdr cdata) - (erc-channel-user-owner (cdr cdata)))))) - -(defun erc-channel-user-admin-p (nick) - "Return non-nil if NICK is an admin in the current channel." - (and nick - (hash-table-p erc-channel-users) - (let ((cdata (erc-get-channel-user nick))) - (and cdata (cdr cdata) - (erc-channel-user-admin (cdr cdata)))))) - -(defun erc-channel-user-op-p (nick) - "Return non-nil if NICK is an operator in the current channel." - (and nick - (hash-table-p erc-channel-users) - (let ((cdata (erc-get-channel-user nick))) - (and cdata (cdr cdata) - (erc-channel-user-op (cdr cdata)))))) - -(defun erc-channel-user-halfop-p (nick) - "Return non-nil if NICK is a half-operator in the current channel." - (and nick - (hash-table-p erc-channel-users) - (let ((cdata (erc-get-channel-user nick))) - (and cdata (cdr cdata) - (erc-channel-user-halfop (cdr cdata)))))) - -(defun erc-channel-user-voice-p (nick) - "Return non-nil if NICK has voice in the current channel." - (and nick - (hash-table-p erc-channel-users) - (let ((cdata (erc-get-channel-user nick))) - (and cdata (cdr cdata) - (erc-channel-user-voice (cdr cdata)))))) - -(defun erc-get-channel-user-list () - "Return a list of users in the current channel. -Each element of the list is of the form (USER . CHANNEL-DATA), -where USER is an erc-server-user struct, and CHANNEL-DATA is -either nil or an erc-channel-user struct. - -See also: `erc-sort-channel-users-by-activity'." - (let (users) - (if (hash-table-p erc-channel-users) - (maphash (lambda (_nick cdata) - (setq users (cons cdata users))) - erc-channel-users)) - users)) - -(defun erc-get-server-nickname-list () - "Return a list of known nicknames on the current server." - (erc-with-server-buffer - (let (nicks) - (when (hash-table-p erc-server-users) - (maphash (lambda (_n user) - (setq nicks - (cons (erc-server-user-nickname user) - nicks))) - erc-server-users) - nicks)))) - -(defun erc-get-channel-nickname-list () - "Return a list of known nicknames on the current channel." - (let (nicks) - (when (hash-table-p erc-channel-users) - (maphash (lambda (_n cdata) - (setq nicks - (cons (erc-server-user-nickname (car cdata)) - nicks))) - erc-channel-users) - nicks))) - -(defun erc-get-server-nickname-alist () - "Return an alist of known nicknames on the current server." - (erc-with-server-buffer - (let (nicks) - (when (hash-table-p erc-server-users) - (maphash (lambda (_n user) - (setq nicks - (cons (cons (erc-server-user-nickname user) nil) - nicks))) - erc-server-users) - nicks)))) - -(defun erc-get-channel-nickname-alist () - "Return an alist of known nicknames on the current channel." - (let (nicks) - (when (hash-table-p erc-channel-users) - (maphash (lambda (_n cdata) - (setq nicks - (cons (cons (erc-server-user-nickname (car cdata)) nil) - nicks))) - erc-channel-users) - nicks))) - -(defun erc-sort-channel-users-by-activity (list) - "Sort LIST such that users which have spoken most recently are listed first. -LIST must be of the form (USER . CHANNEL-DATA). - -See also: `erc-get-channel-user-list'." - (sort list - (lambda (x y) - (when (and (cdr x) (cdr y)) - (let ((tx (erc-channel-user-last-message-time (cdr x))) - (ty (erc-channel-user-last-message-time (cdr y)))) - (and tx - (or (not ty) - (time-less-p ty tx)))))))) - -(defun erc-sort-channel-users-alphabetically (list) - "Sort LIST so that users' nicknames are in alphabetical order. -LIST must be of the form (USER . CHANNEL-DATA). - -See also: `erc-get-channel-user-list'." - (sort list - (lambda (x y) - (when (and (cdr x) (cdr y)) - (let ((nickx (downcase (erc-server-user-nickname (car x)))) - (nicky (downcase (erc-server-user-nickname (car y))))) - (and nickx - (or (not nicky) - (string-lessp nickx nicky)))))))) - -(defvar-local erc-channel-topic nil - "A topic string for the channel. Should only be used in channel-buffers.") - -(defvar-local erc-channel-modes nil - "List of letters, as strings, representing channel modes. -For example, (\"i\" \"m\" \"s\"). Modes that take accompanying -parameters are not included.") - -(defvar-local erc-insert-marker nil - "The place where insertion of new text in erc buffers should happen.") - -(defvar-local erc-input-marker nil - "The marker where input should be inserted.") - -(defun erc-string-no-properties (string) - "Return a copy of STRING will all text-properties removed." - (let ((newstring (copy-sequence string))) - (set-text-properties 0 (length newstring) nil newstring) - newstring)) - -(defcustom erc-prompt "ERC>" - "Prompt used by ERC. Trailing whitespace is not required." - :group 'erc-display - :type '(choice string - (function-item :tag "Interpret format specifiers" - erc-prompt-format) - function)) - -(defvar erc--prompt-format-face-example - #("%p%m%a\u00b7%b>" - 0 2 (font-lock-face erc-my-nick-prefix-face) - 2 4 (font-lock-face font-lock-keyword-face) - 4 6 (font-lock-face erc-error-face) - 6 7 (font-lock-face shadow) - 7 9 (font-lock-face font-lock-constant-face) - 9 10 (font-lock-face shadow)) - "An example value for option `erc-prompt-format' with faces.") - -(defcustom erc-prompt-format erc--prompt-format-face-example - "Format string when `erc-prompt' is `erc-prompt-format'. -ERC recognizes these substitution specifiers: - - %a - away indicator - %b - buffer name - %t - channel or query target, server domain, or dialed address - %S - target@network or buffer name - %s - target@server or server - %N - current network, like Libera.Chat - %p - channel membership prefix, like @ or + - %n - current nickname - %c - channel modes with args for select modes - %C - channel modes with all args - %u - user modes - %m - channel modes sans args in channels, user modes elsewhere - %M - like %m but show nothing in query buffers - -To pick your own colors, do something like: - - (setopt erc-prompt-format - (concat - (propertize \"%b\" \\='font-lock-face \\='erc-input-face) - (propertize \"%a\" \\='font-lock-face \\='erc-error-face))) - -Please remember that ERC ignores this option completely unless -the \"parent\" option `erc-prompt' is set to `erc-prompt-format'." - :package-version '(ERC . "5.6") - :group 'erc-display - :type `(choice (const :tag "{Prefix}{Mode}{Away}{MIDDLE DOT}{Buffer}>" - ,erc--prompt-format-face-example) - string)) - -(defun erc-prompt-format () - "Make predefined `format-spec' substitutions. - -See option `erc-prompt-format' and option `erc-prompt'." - (format-spec erc-prompt-format - (erc-compat--defer-format-spec-in-buffer - (?C erc--channel-modes 3 ",") - (?M erc--format-modes 'no-query-p) - (?N erc-format-network) - (?S erc-format-target-and/or-network) - (?a erc--format-away-indicator) - (?b buffer-name) - (?c erc-format-channel-modes) - (?m erc--format-modes) - (?n erc-current-nick) - (?p erc--format-channel-status-prefix) - (?s erc-format-target-and/or-server) - (?t erc-format-target) - (?u erc--format-user-modes)) - 'ignore-missing)) ; formerly `only-present' - -(defun erc-prompt () - "Return the input prompt as a string. - -See also the variable `erc-prompt'." - (let ((prompt (if (functionp erc-prompt) - (funcall erc-prompt) - erc-prompt))) - (if (> (length prompt) 0) - (concat prompt " ") - prompt))) - -(defcustom erc-notice-prefix "*** " - "Prefix for all notices." - :group 'erc-display - :type 'string) - -(defcustom erc-notice-highlight-type 'all - "Determines how to highlight notices. -See `erc-notice-prefix'. - -The following values are allowed: - - `prefix' - highlight notice prefix only - `all' - highlight the entire notice - -Any other value disables notice's highlighting altogether." - :group 'erc-display - :type '(choice (const :tag "highlight notice prefix only" prefix) - (const :tag "highlight the entire notice" all) - (const :tag "don't highlight notices at all" nil))) - -(defcustom erc-echo-notice-hook nil - "List of functions to call to echo a private notice. -Each function is called with four arguments, the string -to display, the parsed server message, the target buffer (or -nil), and the sender. The functions are called in order, until a -function evaluates to non-nil. These hooks are called after -those specified in `erc-echo-notice-always-hook'. - -See also: `erc-echo-notice-always-hook', -`erc-echo-notice-in-default-buffer', -`erc-echo-notice-in-target-buffer', -`erc-echo-notice-in-minibuffer', -`erc-echo-notice-in-server-buffer', -`erc-echo-notice-in-active-non-server-buffer', -`erc-echo-notice-in-active-buffer', -`erc-echo-notice-in-user-buffers', -`erc-echo-notice-in-user-and-target-buffers', -`erc-echo-notice-in-first-user-buffer'." - :group 'erc-hooks - :type 'hook - :options '(erc-echo-notice-in-default-buffer - erc-echo-notice-in-target-buffer - erc-echo-notice-in-minibuffer - erc-echo-notice-in-server-buffer - erc-echo-notice-in-active-non-server-buffer - erc-echo-notice-in-active-buffer - erc-echo-notice-in-user-buffers - erc-echo-notice-in-user-and-target-buffers - erc-echo-notice-in-first-user-buffer)) - -(defcustom erc-echo-notice-always-hook - '(erc-echo-notice-in-default-buffer) - "List of functions to call to echo a private notice. -Each function is called with four arguments, the string -to display, the parsed server message, the target buffer (or -nil), and the sender. The functions are called in order, and all -functions are called. These hooks are called before those -specified in `erc-echo-notice-hook'. - -See also: `erc-echo-notice-hook', -`erc-echo-notice-in-default-buffer', -`erc-echo-notice-in-target-buffer', -`erc-echo-notice-in-minibuffer', -`erc-echo-notice-in-server-buffer', -`erc-echo-notice-in-active-non-server-buffer', -`erc-echo-notice-in-active-buffer', -`erc-echo-notice-in-user-buffers', -`erc-echo-notice-in-user-and-target-buffers', -`erc-echo-notice-in-first-user-buffer'." - :group 'erc-hooks - :type 'hook - :options '(erc-echo-notice-in-default-buffer - erc-echo-notice-in-target-buffer - erc-echo-notice-in-minibuffer - erc-echo-notice-in-server-buffer - erc-echo-notice-in-active-non-server-buffer - erc-echo-notice-in-active-buffer - erc-echo-notice-in-user-buffers - erc-echo-notice-in-user-and-target-buffers - erc-echo-notice-in-first-user-buffer)) - -;; other tunable parameters - -(defcustom erc-whowas-on-nosuchnick nil - "If non-nil, do a whowas on a nick if no such nick." - :group 'erc - :type 'boolean) - -(defcustom erc-verbose-server-ping nil - "If non-nil, show every time you get a PING or PONG from the server." - :group 'erc-paranoia - :type 'boolean) - -(defcustom erc-public-away-p nil - "Let others know you are back when you are no longer marked away. -This happens in this form: -* is back (gone for