>From 7def5db8d6272380acb4bd871becfeb0e96ce4de Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Wed, 9 Nov 2022 00:16:50 -0800 Subject: [PATCH 0/6] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (6): Teach thing-at-point to recognize bracketed IPv6 URLs Accommodate ircs:// URLs in url-irc and browse-url Refactor erc-select-read-args Default to TLS port when calling erc-tls from lisp Add optional server param to erc-networks--determine Improve new connections in erc-handle-irc-url doc/misc/erc.texi | 39 +++++ etc/NEWS | 20 +++ lisp/erc/erc-backend.el | 6 + lisp/erc/erc-compat.el | 15 ++ lisp/erc/erc-networks.el | 9 +- lisp/erc/erc.el | 200 ++++++++++++++++-------- lisp/net/browse-url.el | 24 +++ lisp/thingatpt.el | 2 +- lisp/url/url-irc.el | 32 +++- test/lisp/erc/erc-networks-tests.el | 17 +++ test/lisp/erc/erc-tests.el | 226 ++++++++++++++++++++++++++++ test/lisp/net/browse-url-tests.el | 9 ++ test/lisp/thingatpt-tests.el | 3 + 13 files changed, 527 insertions(+), 75 deletions(-) Interdiff: diff --git a/etc/NEWS b/etc/NEWS index ab64eff74e..500ac5e50b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -438,6 +438,12 @@ The user options 'url-gateway-rlogin-host', 'url-gateway-rlogin-parameters', and 'url-gateway-rlogin-user-name' are also obsolete. +--- +** The user function 'url-irc-function' now takes a 'scheme' argument. +The user option 'url-irc-function' is now called with a sixth argument +corresponding to the scheme portion of the target URL. For example, +this would be "ircs" for a URL like "ircs://irc.libera.chat". + --- ** The linum.el library is now obsolete. We recommend using either the built-in 'display-line-numbers-mode', or @@ -2616,6 +2622,17 @@ This user option decides which URL scheme that 'browse-url' and related functions will use by default. For example, you could customize this to "https" to always prefer HTTPS URLs. +--- +*** New user option 'browse-url-irc-function'. +This option specifies a function for opening irc:// links. It +defaults to the new function 'browse-url-irc'. + +--- +*** New function 'browse-url-irc'. +This multipurpose autoloaded function can be used for opening irc:// +and ircs:// URLS by any caller that passes a URL string as an initial +arg. + --- *** Support for the Netscape web browser has been removed. This support has been obsolete since Emacs 25.1. The final version of @@ -2842,6 +2859,9 @@ remote host are shown. Alternatively, the user option *** 'outlineify-sticky' command is renamed to 'allout-outlinify-sticky'. The old name is still available as an obsolete function alias. +--- +*** The url-irc library now understands ircs:// links. + --- *** New command 'world-clock-copy-time-as-kill' for 'M-x world-clock'. It copies the current line into the kill ring. diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 3c9293e28a..51a97c8de1 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -1534,15 +1534,6 @@ erc-reuse-buffers (make-obsolete-variable 'erc-reuse-buffers "old behavior when t now permanent" "29.1") -(defcustom erc-legacy-port-names 'legacy - "Interpret \"irc\" and \"ircs\" using IANA service mappings. -When non-nil, this yields 194 and 994 instead of 6667 and 6697. -When set to `legacy', it also emits a warning saying that the -default will change to nil in the future." - :group 'erc - :package-version '(ERC . "5.4.1") ; FIXME increment on ELPA release - :type '(choice (const nil) (const legacy) (const t))) - (defun erc-normalize-port (port) "Normalize the port specification PORT to integer form. PORT may be an integer, a string or a symbol. If it is a string or a @@ -1551,8 +1542,8 @@ erc-normalize-port * ircs -> 994 * ircd -> 6667 * ircd-dalnet -> 7000" - ;; These were updated in 2022 to reflect modern standards and - ;; practices. See also: + ;; These were updated somewhat in 2022 to reflect modern standards + ;; and practices. See also: ;; ;; https://datatracker.ietf.org/doc/html/rfc7194#section-1 ;; https://www.iana.org/assignments/service-names-port-numbers @@ -1564,20 +1555,14 @@ erc-normalize-port (cond ((> port-nr 0) port-nr) - ((string-equal port "ircu") 6667) - ((string-equal port "ircs-u") 6697) - ((member port '("irc" "ircs")) - (when (eq erc-legacy-port-names 'legacy) - (lwarn 'ERC 'warning - (concat "`erc-legacy-port-names' will default to nil " - "in a future version of ERC."))) - (if (string= port "irc") - (if erc-legacy-port-names 194 6667) - (if erc-legacy-port-names 994 6697))) + ((string-equal port "irc") + 194) ((string-equal port "ircs") 994) - ((string-equal port "ircd") + ((string-equal port "ircu") 6667) ; 6665-6669 + ((string-equal port "ircd") ; nonstandard (irc-serv is 529) 6667) + ((string-equal port "ircs-u") 6697) ((string-equal port "ircd-dalnet") 7000) (t @@ -7186,16 +7171,15 @@ erc-get-parsed-vector-type (defcustom erc-url-connect-function nil "When non-nil, a function used to connect to an IRC URL. -Called with any number of keyword arguments recognized by `erc' -and `erc-tls'. The variable `url-current-object', if non-nil, -can be used to help determine whether to connect using TLS." +Called with a string meant to represent a URL scheme, like +\"ircs\", followed by any number of keyword arguments recognized +by `erc' and `erc-tls'." :group 'erc :package-version '(ERC . "5.4.1") ; FIXME increment on release :type '(choice (const nil) function)) -(defun erc--url-default-connect-function (&rest plist) - (let* ((scheme (and url-current-object (url-type url-current-object))) - (ircsp (if scheme +(defun erc--url-default-connect-function (scheme &rest plist) + (let* ((ircsp (if scheme (string-suffix-p "s" scheme) (or (eql 6697 (plist-get plist :port)) (yes-or-no-p "Connect using TLS? ")))) @@ -7210,15 +7194,8 @@ erc--url-default-connect-function (setq ircsp (eql 6697 erc-port))) (apply (if ircsp #'erc-tls #'erc) args))) -;; The current spec, unlike the 2003 Butcher draft, doesn't explicitly -;; allow for an auth[:password]@ component (or trailing ,flags or -;; &options). -;; -;; https://www.iana.org/assignments/uri-schemes -;; https://datatracker.ietf.org/doc/html/draft-butcher-irc-url#section-6 - ;;;###autoload -(defun erc-handle-irc-url (host port channel nick password) +(defun erc-handle-irc-url (host port channel nick password scheme) "Use ERC to IRC on HOST:PORT in CHANNEL. If ERC is already connected to HOST:PORT, simply /join CHANNEL. Otherwise, connect to HOST:PORT as NICK and /join CHANNEL. @@ -7247,6 +7224,7 @@ erc-handle-irc-url (setq deferred t server-buffer (apply (or erc-url-connect-function #'erc--url-default-connect-function) + scheme :server host `(,@(and port (list :port port)) ,@(and nick (list :nick nick)) diff --git a/lisp/net/browse-url.el b/lisp/net/browse-url.el index 8d95c0667b..7ac6396d31 100644 --- a/lisp/net/browse-url.el +++ b/lisp/net/browse-url.el @@ -222,6 +222,14 @@ browse-url-man-function (function :tag "Other function")) :version "26.1") +(defcustom browse-url-irc-function 'browse-url-irc + "Function to open an irc:// link." + :type '(choice + (function-item :tag "Emacs IRC" :value browse-url-irc) + (const :tag "None" nil) + (function :tag "Other function")) + :version "29.1") + (defcustom browse-url-button-regexp (concat "\\b\\(\\(www\\.\\|\\(s?https?\\|ftp\\|file\\|gopher\\|gemini\\|" @@ -547,6 +555,11 @@ browse-url--browser-kind-man (function-put 'browse-url--man 'browse-url-browser-kind #'browse-url--browser-kind-man) +(defun browse-url--irc (url &rest args) + "Call `browse-url-irc-function' with URL and ARGS." + (funcall browse-url-irc-function url args)) +(function-put 'browse-url--irc 'browse-url-browser-kind 'internal) + (defun browse-url--browser (url &rest args) "Call `browse-url-browser-function' with URL and ARGS." (funcall browse-url-browser-function url args)) @@ -565,7 +578,7 @@ browse-url--non-html-file-url-p (defvar browse-url-default-handlers '(("\\`mailto:" . browse-url--mailto) ("\\`man:" . browse-url--man) - ("\\`irc6?s?://" . browse-url-irc) + ("\\`irc6?s?://" . browse-url--irc) (browse-url--non-html-file-url-p . browse-url-emacs)) "Like `browse-url-handlers' but populated by Emacs and packages. diff --git a/lisp/url/url-irc.el b/lisp/url/url-irc.el index 0dd25b7f49..f97b6de6fe 100644 --- a/lisp/url/url-irc.el +++ b/lisp/url/url-irc.el @@ -39,15 +39,12 @@ url-irc-function CHANNEL - What channel on the server to visit right away (can be nil) USER - What username to use PASSWORD - What password to use. - -The variable `url-current-object' is bound to the parsed `url' -struct, but its members may not match the positional args above, -which should take precedence. For example, `:portspec' may be -nil while PORT is 6667." + SCHEME - a URI scheme, such as \"irc\" or \"ircs\"" :type '(choice (const :tag "rcirc" :value url-irc-rcirc) (const :tag "ERC" :value url-irc-erc) (const :tag "ZEN IRC" :value url-irc-zenirc) (function :tag "Other")) + :version "29.1" ; Added SCHEME :group 'url) ;; External. @@ -56,7 +53,7 @@ url-irc-function (defvar zenirc-server-alist) (defvar zenirc-buffer-name) -(defun url-irc-zenirc (host port channel user password) +(defun url-irc-zenirc (host port channel user password _) (let ((zenirc-buffer-name (if (and user host port) (format "%s@%s:%d" user host port) (format "%s:%d" host port))) @@ -70,14 +67,14 @@ url-irc-zenirc (insert "/join " channel) (zenirc-send-line)))) -(defun url-irc-rcirc (host port channel user password) +(defun url-irc-rcirc (host port channel user password _) (let ((chan (when channel (concat "#" channel)))) (rcirc-connect host port user nil nil (when chan (list chan)) password) (when chan (switch-to-buffer (concat chan "@" host))))) -(defun url-irc-erc (host port channel user password) - (erc-handle-irc-url host port channel user password)) +(defun url-irc-erc (host port channel user password scheme) + (erc-handle-irc-url host port channel user password scheme)) ;;;###autoload (defun url-irc (url) @@ -86,14 +83,18 @@ url-irc (pass (url-password url)) (user (url-user url)) (chan (url-filename url)) - (url-current-object url)) + (type (url-type url)) + (compatp (eql 5 (cdr (func-arity url-irc-function))))) (if (url-target url) (setq chan (concat chan "#" (url-target url)))) (if (string-match "^/" chan) (setq chan (substring chan 1 nil))) (if (= (length chan) 0) (setq chan nil)) - (funcall url-irc-function host port chan user pass) + (when compatp + (lwarn 'url :error "Obsolete value for `url-irc-function'")) + (apply url-irc-function + host port chan user pass (unless compatp (list type))) nil)) ;;;; ircs:// diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index e097090e5d..f83e8c8717 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1069,7 +1069,8 @@ erc-tls "bob:changeme" nil nil nil t "bobo" GNU.org)))) ;; Values are often nil when called by lisp code, which leads to - ;; null params. This is why `erc-open' recomputes everything. + ;; null params. This is why `erc-open' recomputes almost + ;; everything. (ert-info ("Fallback") (let ((erc-nick "bob") (erc-server "irc.gnu.org") @@ -1126,43 +1127,43 @@ erc-handle-irc-url (erc-tests--make-server-buf "baznet") (ert-info ("Unknown network") - (erc-handle-irc-url "irc.foonet.org" 6667 "#chan" nil nil) + (erc-handle-irc-url "irc.foonet.org" 6667 "#chan" nil nil "irc") (should (equal '("#chan" nil) (pop calls))) (should-not calls)) (ert-info ("Unknown network, no port") - (erc-handle-irc-url "irc.foonet.org" nil "#chan" nil nil) + (erc-handle-irc-url "irc.foonet.org" nil "#chan" nil nil "irc") (should (equal '("#chan" nil) (pop calls))) (should-not calls)) (ert-info ("Known network, no port") (setq erc-networks-alist '((foonet "irc.foonet.org"))) - (erc-handle-irc-url "irc.foonet.org" nil "#chan" nil nil) + (erc-handle-irc-url "irc.foonet.org" nil "#chan" nil nil "irc") (should (equal '("#chan" nil) (pop calls))) (should-not calls)) (ert-info ("Known network, different port") - (erc-handle-irc-url "irc.foonet.org" 6697 "#chan" nil nil) + (erc-handle-irc-url "irc.foonet.org" 6697 "#chan" nil nil "irc") (should (equal '("#chan" nil) (pop calls))) (should-not calls)) (ert-info ("Known network, existing chan with key") (erc-tests--make-client-buf "foonet" "#chan") - (erc-handle-irc-url "irc.foonet.org" nil "#chan?sec" nil nil) + (erc-handle-irc-url "irc.foonet.org" nil "#chan?sec" nil nil "irc") (should (equal '("#chan" "sec") (pop calls))) (should-not calls)) (ert-info ("Unknown network, connect, no chan") - (erc-handle-irc-url "irc.gnu.org" nil nil nil nil) - (should (equal '(:server "irc.gnu.org") (pop calls))) + (erc-handle-irc-url "irc.gnu.org" nil nil nil nil "irc") + (should (equal '("irc" :server "irc.gnu.org") (pop calls))) (should-not calls)) (ert-info ("Unknown network, connect, chan") (with-current-buffer "foonet" (should-not (local-variable-p 'erc-after-connect))) (setq rvbuf (lambda () (erc-tests--make-server-buf "gnu"))) - (erc-handle-irc-url "irc.gnu.org" nil "#spam" nil nil) - (should (equal '(:server "irc.gnu.org") (pop calls))) + (erc-handle-irc-url "irc.gnu.org" nil "#spam" nil nil "irc") + (should (equal '("irc" :server "irc.gnu.org") (pop calls))) (should-not calls) (with-current-buffer "gnu" (should (local-variable-p 'erc-after-connect)) diff --git a/test/lisp/net/browse-url-tests.el b/test/lisp/net/browse-url-tests.el index cf917802e0..dc81976821 100644 --- a/test/lisp/net/browse-url-tests.el +++ b/test/lisp/net/browse-url-tests.el @@ -58,12 +58,12 @@ browse-url-tests-select-handler-man (ert-deftest browse-url-tests-select-handler-irc () (should (eq (browse-url-select-handler "irc://localhost" 'internal) - 'browse-url-irc)) + 'browse-url--irc)) (should-not (browse-url-select-handler "irc://localhost" 'external)) (should (eq (browse-url-select-handler "irc6://localhost") - 'browse-url-irc)) + 'browse-url--irc)) (should (eq (browse-url-select-handler "ircs://tester@irc.gnu.org/#chan") - 'browse-url-irc))) + 'browse-url--irc))) (ert-deftest browse-url-tests-select-handler-file () (should (eq (browse-url-select-handler "file://foo.txt") -- 2.38.1