diff options
Diffstat (limited to 'lisp/erc/erc-networks.el')
-rw-r--r-- | lisp/erc/erc-networks.el | 193 |
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) |