mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Improve new connections in erc-handle-irc-url
* doc/misc/erc.texi: Add new Integrations section to the info manual under Advanced Usage. * etc/ERC-NEWS: Add new section mentioning improved UX when clicking on irc:// links. * lisp/erc/erc.el (erc-handle-irc-url): Add optional "scheme" parameter. Fix `erc-open' invocation so that the server buffer is named correctly by deferring to a new customizable opener. Arrange for JOINing a channel in a manner similar to ERC's autojoin module. (erc-url-connect-function): Add new option for creating a new ERC connection based on info parsed from a URL. (erc--url-default-connect-function): New function to serve as an interactive-only fallback when a user hasn't specified a URL connect function. * lisp/erc/erc-compat.el (erc-compat--29-browse-url--irc): Add new compatibility function for `browse-url-irc' and include it in `browse-url-default-handlers' on Emacs versions below 29. * test/lisp/erc/erc-tests.el (erc-tests--make-server-buf, erc-tests--make-client-buf): Add helpers for creating dummy ERC buffers. (erc-handle-irc-url): Add test. * test/lisp/erc/erc-scenarios-misc.el (erc-scenarios-handle-irc-url): Add new test. * test/lisp/erc/resources/join/legacy/foonet.eld: Relax timeout. (Bug#56514.)
This commit is contained in:
parent
535cc4c81a
commit
ed5022b4ee
7 changed files with 263 additions and 20 deletions
|
|
@ -7186,25 +7186,83 @@ This function should be on `erc-kill-channel-hook'."
|
|||
;; Teach url.el how to open irc:// URLs with ERC.
|
||||
;; To activate, customize `url-irc-function' to `url-irc-erc'.
|
||||
|
||||
;; FIXME change user to nick, and use API to find server buffer
|
||||
(defcustom erc-url-connect-function nil
|
||||
"When non-nil, a function used to connect to an IRC URL.
|
||||
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 (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? "))))
|
||||
(erc-server (plist-get plist :server))
|
||||
(erc-port (or (plist-get plist :port)
|
||||
(and ircsp (erc-normalize-port 'ircs-u))
|
||||
erc-port))
|
||||
(erc-nick (or (plist-get plist :nick) erc-nick))
|
||||
(erc-password (plist-get plist :password))
|
||||
(args (erc-select-read-args)))
|
||||
(unless ircsp
|
||||
(setq ircsp (eql 6697 erc-port)))
|
||||
(apply (if ircsp #'erc-tls #'erc) args)))
|
||||
|
||||
;;;###autoload
|
||||
(defun erc-handle-irc-url (host port channel user password)
|
||||
"Use ERC to IRC on HOST:PORT in CHANNEL as USER with PASSWORD.
|
||||
(defun erc-handle-irc-url (host port channel nick password &optional 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 USER and /join CHANNEL."
|
||||
(let ((server-buffer
|
||||
(car (erc-buffer-filter
|
||||
(lambda ()
|
||||
(and (string-equal erc-session-server host)
|
||||
(= erc-session-port port)
|
||||
(erc-open-server-buffer-p)))))))
|
||||
(with-current-buffer (or server-buffer (current-buffer))
|
||||
(if (and server-buffer channel)
|
||||
(erc-cmd-JOIN channel)
|
||||
(erc-open host port (or user (erc-compute-nick)) (erc-compute-full-name)
|
||||
(not server-buffer) password nil channel
|
||||
(when server-buffer
|
||||
(get-buffer-process server-buffer)))))))
|
||||
Otherwise, connect to HOST:PORT as NICK and /join CHANNEL.
|
||||
|
||||
Beginning with ERC 5.5, new connections require human intervention.
|
||||
Customize `erc-url-connect-function' to override this."
|
||||
(when (eql port 0) (setq port nil))
|
||||
(let* ((net (erc-networks--determine host))
|
||||
(server-buffer
|
||||
;; Viable matches may slip through the cracks for unknown
|
||||
;; networks. Additional passes could likely improve things.
|
||||
(car (erc-buffer-filter
|
||||
(lambda ()
|
||||
(and (not erc--target)
|
||||
(erc-server-process-alive)
|
||||
;; Always trust a matched network.
|
||||
(or (and net (eq net (erc-network)))
|
||||
(and (string-equal erc-session-server host)
|
||||
;; Ports only matter when dialed hosts
|
||||
;; match and we have sufficient info.
|
||||
(or (not port)
|
||||
(= (erc-normalize-port erc-session-port)
|
||||
port)))))))))
|
||||
key deferred)
|
||||
(unless server-buffer
|
||||
(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))
|
||||
,@(and password `(:password ,password))))))
|
||||
(when channel
|
||||
;; These aren't percent-decoded by default
|
||||
(when (string-prefix-p "%" channel)
|
||||
(setq channel (url-unhex-string channel)))
|
||||
(cl-multiple-value-setq (channel key) (split-string channel "[?]"))
|
||||
(if deferred
|
||||
;; Alternatively, we could make this a defmethod, so when
|
||||
;; autojoin is loaded, it can do its own thing. Also, as
|
||||
;; with `erc-once-with-server-event', it's fine to set local
|
||||
;; hooks here because they're killed when reconnecting.
|
||||
(with-current-buffer server-buffer
|
||||
(letrec ((f (lambda (&rest _)
|
||||
(remove-hook 'erc-after-connect f t)
|
||||
(erc-cmd-JOIN channel key))))
|
||||
(add-hook 'erc-after-connect f nil t)))
|
||||
(with-current-buffer server-buffer
|
||||
(erc-cmd-JOIN channel key))))))
|
||||
|
||||
(provide 'erc)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue