;; erc.el --- An Emacs Internet Relay Chat client -*- lexical-binding:t -*-
-;; Copyright (C) 1997-2015 Free Software Foundation, Inc.
+;; Copyright (C) 1997-2016 Free Software Foundation, Inc.
;; Author: Alexander L. Belikoff (alexander@belikoff.net)
;; Contributors: Sergey Berezin (sergey.berezin@cs.cmu.edu),
;; Kelvin White (kwhite@gnu.org)
;; Maintainer: emacs-devel@gnu.org
;; Keywords: IRC, chat, client, Internet
+
;; Version: 5.3
;; This file is part of GNU Emacs.
;; * http://sv.gnu.org/projects/erc/
;; * http://www.emacswiki.org/cgi-bin/wiki/ERC
+
+
;; As of 2006-06-13, ERC development is now hosted on Savannah
;; (http://sv.gnu.org/projects/erc). I invite everyone who wants to
;; hack on it to contact me <mwolson@gnu.org> in order to get write
;; access to the shared Arch archive.
-;; Installation:
-
-;; Put erc.el in your load-path, and put (require 'erc) in your .emacs.
-
;; Configuration:
;; Use M-x customize-group RET erc RET to get an overview
(defcustom erc-hide-prompt nil
"If non-nil, do not display the prompt for commands.
-\(A command is any input starting with a '/').
+\(A command is any input starting with a `/').
See also the variables `erc-prompt' and `erc-command-indicator'."
:group 'erc-display
(repeat :inline t :tag "Others" (string :tag "IRC Message Type"))))
(defcustom erc-hide-list nil
- "List of IRC type messages to hide.
-A typical value would be '(\"JOIN\" \"PART\" \"QUIT\")."
+ "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 \((\"freenode\" \"MODE\")
+ \(\"OFTC\" \"JOIN\" \"QUIT\"))."
+ :version "25.1"
+ :group 'erc-ignore
+ :type 'erc-message-type)
+
+(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 'erc-message-type)
(defvar erc-channel-modes nil
"List of strings representing channel modes.
-E.g. '(\"i\" \"m\" \"s\" \"b Quake!*@*\")
+E.g. (\"i\" \"m\" \"s\" \"b Quake!*@*\")
\(not sure the ban list will be here, but why not)")
(make-variable-buffer-local 'erc-channel-modes)
"Indicator used by ERC for showing commands.
If non-nil, this will be used in the ERC buffer to indicate
-commands (i.e., input starting with a '/').
+commands (i.e., input starting with a `/').
If nil, the prompt will be constructed from the variable `erc-prompt'."
:group 'erc-display
The following values are allowed:
- 'prefix - highlight notice prefix only
- 'all - highlight the entire notice
+ `prefix' - highlight notice prefix only
+ `all' - highlight the entire notice
Any other value disables notice's highlighting altogether."
:group 'erc-display
As an example:
(setq erc-quit-reason-various-alist
- '((\"xmms\" dme:now-playing)
+ \\='((\"xmms\" dme:now-playing)
(\"version\" erc-quit-reason-normal)
(\"home\" \"Gone home !\")
(\"^$\" \"Default Reason\")))
As an example:
(setq erc-part-reason-various-alist
- '((\"xmms\" dme:now-playing)
+ \\='((\"xmms\" dme:now-playing)
(\"version\" erc-part-reason-normal)
(\"home\" \"Gone home !\")
(\"^$\" \"Default Reason\")))
Example:
- ;;;###autoload (autoload 'erc-replace-mode \"erc-replace\")
+ ;;;###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)))"
+ ((add-hook \\='erc-insert-modify-hook
+ \\='erc-replace-insert))
+ ((remove-hook \\='erc-insert-modify-hook
+ \\='erc-replace-insert)))"
(declare (doc-string 3))
(let* ((sn (symbol-name name))
(mode (intern (format "erc-%s-mode" (downcase sn))))
(defconst erc-default-port 6667
"IRC port to use if it cannot be detected otherwise.")
+(defconst erc-default-port-tls 6697
+ "IRC port to use for encrypted connections if it cannot be
+ detected otherwise.")
+
(defcustom erc-join-buffer 'buffer
"Determines how to display a newly created IRC buffer.
The available choices are:
- 'window - in another window,
- 'window-noselect - in another window, but don't select that one,
- 'frame - in another frame,
- 'bury - bury it in a new buffer,
- 'buffer - in place of the current buffer,
+ `window' - in another window,
+ `window-noselect' - in another window, but don't select that one,
+ `frame' - in another frame,
+ `bury' - bury it in a new buffer,
+ `buffer' - in place of the current buffer,
any other value - in place of the current buffer."
:group 'erc-buffers
:type '(choice (const :tag "Split window and select" window)
;; Only allow ERC buffers in the same session.
(let ((proc (unless arg erc-server-process)))
(lambda (bufname)
- (let ((buf (get-buffer bufname)))
+ (let ((buf (if (consp bufname)
+ (cdr bufname) (get-buffer bufname))))
(when buf
(erc--buffer-p buf (lambda () t) proc)
(with-current-buffer buf
(erc-update-modules)
(set-buffer buffer)
(setq old-point (point))
- (erc-mode)
+ (let ((old-recon-count erc-server-reconnect-count))
+ (erc-mode)
+ (setq erc-server-reconnect-count old-recon-count))
(setq erc-server-announced-name server-announced-name)
(setq erc-server-connected connected-p)
;; connection parameters
(auth-source-search :host server
:max 1
:user nick
- :port port
+ ;; secrets.el wouldn’t accept a number
+ :port (if (numberp port) (number-to-string port) port)
:require '(:secret)))
:secret)))
(if (functionp secret)
(defun erc-tls (&rest r)
"Interactively select TLS connection parameters and run ERC.
Arguments are the same as for `erc'."
- (interactive (erc-select-read-args))
+ (interactive (let ((erc-default-port erc-default-port-tls))
+ (erc-select-read-args)))
(let ((erc-server-connect-function 'erc-open-tls-stream))
(apply #'erc r)))
The process will be given the name NAME, its target buffer will be
BUFFER. HOST and PORT specify the connection target."
(open-network-stream name buffer host port
+ :nowait t
:type 'tls))
;;; Displaying error messages
"Display STRING in the ERC BUFFER.
All screen output must be done through this function. If BUFFER is nil
or omitted, the default ERC buffer for the `erc-session-server' is used.
-The BUFFER can be an actual buffer, a list of buffers, 'all or 'active.
-If BUFFER = 'all, the string is displayed in all the ERC buffers for the
-current session. 'active means the current active buffer
+The BUFFER can be an actual buffer, a list of buffers, `all' or `active'.
+If BUFFER = `all', the string is displayed in all the ERC buffers for the
+current session. `active' means the current active buffer
\(`erc-active-buffer'). If the buffer can't be resolved, the current
buffer is used. `erc-display-line-1' is used to display STRING.
(defcustom erc-lurker-trim-nicks t
"If t, trim trailing `erc-lurker-ignore-chars' from nicks.
-This causes e.g. nick and nick` to be considered as the same
+This causes e.g. nick and nick\\=` to be considered as the same
individual for activity tracking and lurkiness detection
purposes."
:group 'erc-lurker
(defcustom erc-lurker-hide-list nil
"List of IRC type messages to hide when sent by lurkers.
-A typical value would be '(\"JOIN\" \"PART\" \"QUIT\").
+A typical value would be \(\"JOIN\" \"PART\" \"QUIT\").
See also `erc-lurker-p' and `erc-hide-list'."
:group 'erc-lurker
:type 'erc-message-type)
erc-common-server-suffixes))
erc-server-announced-name)))
+(defun erc-add-targets (scope target-list)
+ (let ((targets
+ (mapcar (lambda (targets) (member scope targets)) target-list)))
+ (cdr (apply 'append (delete nil targets)))))
+
(defun erc-hide-current-message-p (parsed)
"Predicate indicating whether the parsed ERC response PARSED should be hidden.
Messages are always hidden if the message type of PARSED appears in
-`erc-hide-list'. In addition, messages whose type is a member of
-`erc-lurker-hide-list' are hidden if `erc-lurker-p' returns true."
+`erc-hide-list'. Message types that appear in `erc-network-hide-list'
+or `erc-channel-hide-list' are are only hidden if the target matches
+the network or channel in the list. In addition, messages whose type
+is a member of `erc-lurker-hide-list' are hidden if `erc-lurker-p'
+returns non-nil."
(let* ((command (erc-response.command parsed))
- (sender (car (erc-parse-user (erc-response.sender parsed)))))
+ (sender (car (erc-parse-user (erc-response.sender parsed))))
+ (channel (nth 1 (erc-response.command-args parsed)))
+ (network (or (and (fboundp 'erc-network-name) (erc-network-name))
+ (erc-shorten-server-name
+ (or erc-server-announced-name
+ erc-session-server))))
+ (current-hide-list
+ (when erc-network-hide-list
+ (erc-add-targets network erc-network-hide-list)))
+ (current-hide-list
+ (apply 'append current-hide-list
+ (when erc-channel-hide-list
+ (erc-add-targets channel erc-channel-hide-list)))))
(or (member command erc-hide-list)
+ (member command current-hide-list)
(and (member command erc-lurker-hide-list) (erc-lurker-p sender)))))
(defun erc-display-message (parsed type buffer msg &rest args)
(defun erc-cmd-SAY (line)
"Send LINE to the current query or channel as a message, not a command.
-Use this when you want to send a message with a leading '/'. Note
+Use this when you want to send a message with a leading `/'. Note
that since multi-line messages are never a command, you don't
need this when pasting multiple lines of text."
(if (string-match "^\\s-*$" line)
If FUNC contains a valid function or variable, help about that
will be displayed. If FUNC is empty, display an apropos about
ERC commands. Otherwise, do `apropos' in the ERC namespace
-\(\"erc-.*LINE\"\).
+\(\"erc-.*LINE\").
Examples:
To find out about erc and bbdb, do
(erc-display-message nil 'error (current-buffer)
'cannot-read-file ?f file))
(t
- (message "Loading \'%s\'..." file)
+ (message "Loading `%s'..." file)
(erc-load-script file)
- (message "Loading \'%s\'...done" file))))
+ (message "Loading `%s'...done" file))))
t)
(t nil)))
(put 'erc-cmd-ME 'do-not-parse-args t)
(defun erc-cmd-ME\'S (line)
- "Do a /ME command, but add the string \" 's\" to the beginning."
+ "Do a /ME command, but add the string \" \\='s\" to the beginning."
(erc-cmd-ME (concat " 's" line)))
(put 'erc-cmd-ME\'S 'do-not-parse-args t)
It serves as a menu to find any of the occurrences in this buffer.
\\[describe-mode] in that buffer will explain how.
-If LINE contains upper case characters (excluding those preceded by `\'),
+If LINE contains upper case characters (excluding those preceded by `\\'),
the matching is case-sensitive."
(occur line)
t)
;; server's setting if we haven't
;; established a connection yet
(- 9 (length erc-nick-uniquifier))))
- erc-nick-uniquifier)))
+ erc-nick-uniquifier)))
(erc-cmd-NICK newnick)
(erc-display-error-notice
nil
"Handle the logging in process of connection."
(unless erc-logged-in
(setq erc-logged-in t)
- (message "Logging in as \'%s\'... done" (erc-current-nick))
+ (message "Logging in as `%s'... done" (erc-current-nick))
;; execute a startup script
(let ((f (erc-select-startup-file)))
(when f
(nick (car (erc-response.command-args parsed)))
(buffer (process-buffer proc)))
(setq erc-server-connected t)
+ (setq erc-server-reconnect-count 0)
(erc-update-mode-line)
(erc-set-initial-user-mode nick buffer)
(erc-server-setup-periodical-ping buffer)
(_ (error "Unknown prefix char `%S'" ch) voice))
'on)))
(when updatep
+ ;; If we didn't issue the NAMES request (consider two clients
+ ;; talking to an IRC proxy), `erc-channel-begin-receiving-names'
+ ;; will not have been called, so we have to do it here.
+ (unless erc-channel-new-member-names
+ (erc-channel-begin-receiving-names))
(puthash (erc-downcase name) t
erc-channel-new-member-names)
(erc-update-current-channel-member
(defun erc-update-channel-topic (channel topic &optional modify)
"Find a buffer for CHANNEL and set the TOPIC for it.
-If optional MODIFY is 'append or 'prepend, then append or prepend the
+If optional MODIFY is `append' or `prepend', then append or prepend the
TOPIC string to the current topic."
(erc-with-buffer (channel)
(cond ((eq modify 'append)
(t (setq erc-channel-user-limit nil))))))
(defun erc-update-channel-key (channel onoff key)
- "Update CHANNEL's key to KEY if ONOFF is 'on or to nil if it's 'off."
+ "Update CHANNEL's key to KEY if ONOFF is `on' or to nil if it's `off'."
(erc-with-buffer
(channel)
(cond ((eq onoff 'on) (setq erc-channel-key key))
Event TYPE L
- nickname change 'nick (NEW-NICK)"
+ nickname change `nick' (NEW-NICK)"
(erc-log (format "user-change: type: %S nlh: %S l: %S" type nlh l))
(cond
;; nickname change
. "\n\nConnection failed! Not re-establishing connection.\n")
(finished . "\n\n*** ERC finished ***\n")
(terminated . "\n\n*** ERC terminated: %e\n")
- (login . "Logging in as \'%n\'...")
+ (login . "Logging in as `%n'...")
(nick-in-use . "%n is in use. Choose new nickname: ")
(nick-too-long
. "WARNING: Nick length (%i) exceeds max NICKLEN(%l) defined by server")
(cond
((eq (erc-server-buffer) (current-buffer))
(run-hooks 'erc-kill-server-hook))
- ((erc-channel-p (erc-default-target))
+ ((erc-channel-p (or (erc-default-target) (buffer-name)))
(run-hooks 'erc-kill-channel-hook))
(t
(run-hooks 'erc-kill-buffer-hook)))))
(text-property-not-all (point-min) (point-max) 'erc-parsed nil))
(defun erc-restore-text-properties ()
- "Restore the property 'erc-parsed for the region."
+ "Restore the property `erc-parsed' for the region."
(let ((parsed-posn (erc-find-parsed-property)))
(put-text-property
(point-min) (point-max)