summaryrefslogtreecommitdiff
path: root/lisp/erc/erc-networks.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/erc/erc-networks.el')
-rw-r--r--lisp/erc/erc-networks.el193
1 files changed, 114 insertions, 79 deletions
diff --git a/lisp/erc/erc-networks.el b/lisp/erc/erc-networks.el
index e2893a9c9e0..1b26afa1164 100644
--- a/lisp/erc/erc-networks.el
+++ b/lisp/erc/erc-networks.el
@@ -29,8 +29,6 @@
;;
;; This is the "networks" module.
;;
-;; M-x erc-server-select provides an alternative way to connect to servers by
-;; choosing networks.
;; You can use (eq (erc-network) 'Network) if you'd like to set variables or do
;; certain actions according to which network you're connected to.
;; If a network you use is not listed in `erc-networks-alist', you can put
@@ -44,29 +42,25 @@
(defvar erc--target)
(defvar erc-insert-marker)
-(defvar erc-kill-buffer-hook)
-(defvar erc-kill-server-hook)
(defvar erc-modules)
(defvar erc-rename-buffers)
(defvar erc-reuse-buffers)
(defvar erc-server-announced-name)
(defvar erc-server-connected)
-(defvar erc-server-parameters)
(defvar erc-server-process)
-(defvar erc-session-server)
-(declare-function erc--default-target "erc" nil)
(declare-function erc--get-isupport-entry "erc-backend" (key &optional single))
(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-error "erc" (&rest args))
(declare-function erc-get-buffer "erc" (target &optional proc))
-(declare-function erc-server-buffer "erc" nil)
(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
@@ -255,6 +249,7 @@
("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)))
@@ -315,13 +310,15 @@
("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" 6667)
- ("Libera.Chat: Random Europe server" Libera.Chat "irc.eu.libera.chat" 6667)
- ("Libera.Chat: Random US & Canada server" Libera.Chat "irc.us.libera.chat" 6667)
- ("Libera.Chat: Random Australia & New Zealand server" Libera.Chat "irc.au.libera.chat" 6667)
- ("Libera.Chat: Random East Asia server" Libera.Chat "irc.ea.libera.chat" 6667)
- ("Libera.Chat: IPv4 only server" Libera.Chat "irc.ipv4.libera.chat" 6667)
- ("Libera.Chat: IPv6 only server" Libera.Chat "irc.ipv6.libera.chat" 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)
@@ -346,7 +343,7 @@
("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))
+ ("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)
@@ -469,12 +466,13 @@
("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) where
+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 servers hostname and
-PORTS is either a number, a list of numbers, or a list of port ranges."
+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")
@@ -483,7 +481,15 @@ PORTS is either a number, a list of numbers, or a list of port ranges."
(repeat :tag "List of ports or ranges"
(choice (integer :tag "Port number")
(list :tag "Port range"
- integer integer)))))))
+ 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")
@@ -743,9 +749,8 @@ PORTS is either a number, a list of numbers, or a list of port ranges."
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 regexp, it's used to match against
- `erc-server-announced-name'. It can also be a function (predicate).
- Then it is executed with the server buffer as current buffer."
+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")
@@ -979,12 +984,11 @@ object."
(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--default-target
- (when-let* ((new-name (erc-networks--reconcile-buffer-names erc--target
- nid))
- ((not (equal (buffer-name) new-name))))
- (rename-buffer new-name 'unique))))
+ (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.")
@@ -1119,10 +1123,27 @@ TARGET to be an `erc--target' object."
(lambda ()
(when (and erc--target (eq (erc--target-symbol erc--target)
(erc--target-symbol target)))
- (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))))))))
+ ;; 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.")
@@ -1219,6 +1240,8 @@ 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)
@@ -1282,18 +1305,16 @@ shutting down the connection."
erc-network)))
(erc-display-message parsed 'notice nil m)
nil)
- ((and
- (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).
- (let m (concat "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.")))
- (require 'info)
- (erc-display-error-notice parsed m)
+ ((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
@@ -1311,12 +1332,11 @@ shutting down the connection."
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
- (setq erc-server-announced-name (erc-response.sender parsed))
- (erc-display-error-notice
- parsed (concat "Failed to determine server name. Using \""
- erc-server-announced-name "\" instead."
- " If this was unexpected, consider reporting it via "
- (substitute-command-keys "\\[erc-bug]") ".")))
+ (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)
@@ -1374,6 +1394,8 @@ 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.
Must be called from the replacement buffer."
+ (defvar erc-kill-buffer-hook)
+ (defvar erc-kill-server-hook)
;; ERC expects `erc-open' to be idempotent when setting up local
;; vars and other context properties for a new identity. Thus, it's
;; unlikely we'll have to copy anything else over besides text. And
@@ -1458,6 +1480,7 @@ to be a false alarm. If `erc-reuse-buffers' is nil, let
;; 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)))
@@ -1494,12 +1517,9 @@ to be a false alarm. If `erc-reuse-buffers' is nil, let
(memq (erc--target-symbol erc--target)
erc-networks--bouncer-targets)))
proc)
- (let ((m (concat "Unexpected state detected. If you've just issued an"
- " /MOTD, please know that the command is bugged in ERC"
- " 5.5 (Emacs 29) but will be fixed in the next release."
- " Otherwise, please report this occurrence via"
- (substitute-command-keys " \\[erc-bug]."))))
- (erc-display-error-notice parsed m))))
+ (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)
@@ -1517,7 +1537,6 @@ to be a false alarm. If `erc-reuse-buffers' is nil, let
"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)
- (require 'info nil t)
(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.
@@ -1538,7 +1557,7 @@ As an example:
(erc-ports-list \\='((1 5))) => (1 2 3 4 5)
(erc-ports-list \\='(1 (3 5))) => (1 3 4 5)"
(let (result)
- (dolist (p ports)
+ (dolist (p (ensure-list ports))
(cond ((numberp p)
(push p result))
((listp p)
@@ -1547,31 +1566,32 @@ As an example:
result)))))
(nreverse result)))
-;;;###autoload
-(defun erc-server-select ()
- "Interactively select a server to connect to using `erc-server-alist'."
- (interactive)
+(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* ((completion-ignore-case t)
(net (intern
(completing-read "Network: "
(delete-dups
(mapcar (lambda (x)
- (list (symbol-name (nth 1 x))))
+ (list (nth 1 x)))
erc-server-alist)))))
- (srv (assoc
- (completing-read "Server: "
- (delq nil
- (mapcar (lambda (x)
- (when (equal (nth 1 x) net)
- x))
- erc-server-alist)))
- erc-server-alist))
+ (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 "Server: " s-entries) s-entries))
(host (nth 2 srv))
- (ports (if (listp (nth 3 srv))
- (erc-ports-list (nth 3 srv))
- (list (nth 3 srv))))
- (port (and ports (seq-random-elt ports))))
- (erc :server host :port port)))
+ (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
@@ -1581,14 +1601,29 @@ As an example:
'((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
@@ -1608,7 +1643,7 @@ VALUE is the options value.")
items nil)))))
val))
-(erc-get 'pals 'Libera.Chat)
+;; (erc-get 'pals 'Libera.Chat)
(provide 'erc-networks)