mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-15 10:30:25 -08:00
Allow custom display-buffer actions in ERC
* doc/misc/erc.texi: Add new section under "Integrations" chapter describing `display-buffer' Custom function choice for ERC's many buffer-display options. * etc/ERC-NEWS: Mention new function variant for all buffer-display options. * lisp/erc/erc-backend.el: Add forward declaration for `erc--called-as-input-p' and `erc--display-context'. (erc--server-reconnect-display-timer, erc--server-last-reconnect-display-reset): Use new name for option `erc-reconnect-display', now `erc-auto-reconnect-display'. (erc--server-determine-join-display-context): New generic function to determine value of `erc--display-context' during JOINs. (erc-server-JOIN, erc-server-PRIVMSG): Set `erc--display-context' to a symbol for the handler's IRC command, like `JOIN', for the benefit of custom `display-buffer'-like functions running in `erc-setup-buffer'. (erc-server-471, erc-server-471-functions, erc-server-473, erc-server-473-functions): New handlers for JOIN rejections. Also remove 471 and 473 from comment at bottom of file. (erc-server-475): Bind `erc--called-as-input-p' so that `erc-cmd-JOIN' sets `erc-interactive-display' context. * lisp/erc/erc-join.el (erc-autojoin-mode, erc-autojoin-enable, erc-autojoin-disable): Kill local variable `erc-join--requested-channels'. Add and remove `erc-join--remove-requested-channels' to/from various server-handler hooks for JOIN rejection numerics. (erc-join--requested-channels): New local variable to remember channels we've attempted to JOIN this session that haven't yet been confirmed by the server. (erc-join--remove-requested-channel): New JOIN rejection handler to stop tracking channel in `erc-join--requested-channels'. (erc--server-determine-join-display-context): module-specific implementation of generic function for `erc-autojoin-mode'. (erc-autojoin--join): Remember channels slated for JOIN'ing. * lisp/erc/erc.el (erc--buffer-display-choices): New helper constant for defining common `:type' for all buffer-display options. (erc-buffer-display, erc-interactive-display, erc-auto-reconnect-display, erc-receive-query-display): Use helper `erc--buffer-display-choices' for defining `:type', which includes a new choice for a `display-buffer'-like function. (erc-reconnect-display, erc-auto-reconnect-display): Alias former to latter, now the preferred name. (erc-reconnect-timeout, erc-auto-reconnect-timeout): Change name from former to latter. This option is new in ERC 5.6. (erc-reconnect-display-server-buffers): New option. (erc-buffer-do): Revise doc string. (erc--display-context): New variable, an alist of "context tokens" to be forwarded as the "action alist" to `erc-buffer-display' functions. (erc-skip-displaying-selected-window-buffer): New variable, deprecated at birth, to act as an escape hatch for folks who don't want to skip the displaying of buffers already showing in the selected window. (erc--display-buffer-overriding-action): Local variable allowing modules to influence the displaying of new ERC buffers independently of user options. (erc-setup-buffer): Do nothing when the selected window already shows current buffer unless user has provided a custom display function. Accommodate new Custom choice function values, like `display-buffer' and `pop-to-buffer'. (erc-open): Run `erc-setup-buffer' when option `erc-reconnect-display-server-buffers' is non-nil, even for existing server buffers. Bind `display-buffer-overriding-action' to the value of `erc--display-buffer-overriding-action' around calls to `erc-setup-buffer'. (erc-select-read-args): Add `erc--display-context' to environment. (erc, erc-tls): Bind `erc--display-context' around calls to `erc-select-read-args' and main body. (erc-cmd-JOIN, erc-cmd-QUERY, erc--cmd-reconnect, erc-handle-irc-url): Add item for `erc-interactive-display' to `erc--display-context'. (erc-connection-established): Update name of `erc-reconnect-display-timeout' to `erc-auto-reconnect-display-timeout'. (erc-message-english-s471, erc-message-english-s473): New variables, format templates for JOIN rejection messages. * test/lisp/erc/erc-scenarios-base-buffer-display.el (erc-scenarios-base-buffer-display--defwin-recbury-intbuf, erc-scenarios-base-buffer-display--defwino-recbury-intbuf, erc-scenarios-base-buffer-display--count-reset-timeout): Use preferred name `erc-auto-reconnect-display' for `erc-reconnect-display'. * test/lisp/erc/erc-scenarios-join-display-context.el: New file. * test/lisp/erc/erc-tests.el (erc--initialize-markers): Fix unrealistic call to `erc-open'. (erc-setup-buffer--custom-action): New test. (erc-select-read-args, erc-tls, erc--interactive, erc-server-select): Expect new environment binding for `erc--display-context'. * test/lisp/erc/resources/join/buffer-display/mode-context.eld: New file. (Bug#62833)
This commit is contained in:
parent
d45770e8d0
commit
b354b3a53b
9 changed files with 617 additions and 83 deletions
|
|
@ -613,6 +613,7 @@ Integrations
|
|||
* URL:: Opening IRC URLs in ERC.
|
||||
* SOCKS:: Connecting to IRC with a SOCKS proxy.
|
||||
* auth-source:: Retrieving auth-source entries with ERC.
|
||||
* display-buffer:: Controlling how ERC displays buffers.
|
||||
|
||||
@end detailmenu
|
||||
@end menu
|
||||
|
|
@ -1226,6 +1227,7 @@ stuff, to the current ERC buffer."
|
|||
|
||||
@menu
|
||||
* auth-source:: Retrieving auth-source entries with ERC.
|
||||
* display-buffer:: Controlling how ERC displays buffers.
|
||||
@end menu
|
||||
|
||||
@anchor{URL}
|
||||
|
|
@ -1468,6 +1470,185 @@ required by certain channels you join. When modifying a traditional
|
|||
@samp{user} field (for example, @samp{login "#fsf"}, in netrc's case).
|
||||
The actual key goes in the @samp{password} (or @samp{secret}) field.
|
||||
|
||||
@node display-buffer
|
||||
@subsection display-buffer
|
||||
@cindex display-buffer
|
||||
|
||||
ERC supports the ``action'' interface used by @code{display-buffer}
|
||||
and friends from @file{window.el}. @xref{Displaying Buffers,,, elisp,
|
||||
Emacs Lisp}, for specifics. When ERC displays a new or
|
||||
``reassociated'' buffer, it consults its various buffer-display
|
||||
options, such as @code{erc-buffer-display}, to decide whether and how
|
||||
the buffer ought to appear in a window. Exactly which one it consults
|
||||
depends on the context in which the buffer is being manifested.
|
||||
|
||||
For some buffer-display options, the context is pretty cut and dry.
|
||||
For instance, in the case of @code{erc-receive-query-display}, you're
|
||||
receiving a query from someone you haven't yet chatted with in the
|
||||
current session. For other options, like
|
||||
@code{erc-interactive-display}, the precise context varies. For
|
||||
example, you might be opening a query buffer with the command
|
||||
@kbd{/QUERY bob @key{RET}} or joining a new channel with @kbd{/JOIN
|
||||
#chan @key{RET}}. Power users wishing to distinguish between such
|
||||
nuanced contexts or just exercise more control over buffer-display
|
||||
behavior generally can elect to override these options by setting one
|
||||
or more to a ``@code{display-buffer}-like'' function that accepts a
|
||||
@var{buffer} and an @var{action} argument.
|
||||
|
||||
@subsubheading Examples
|
||||
|
||||
In this first example, a user-provided buffer-display function
|
||||
displays new server buffers in the current window when issuing an
|
||||
@kbd{M-x erc-tls @key{RET}} and in a split window for all other
|
||||
interactve contexts covered by the option
|
||||
@code{erc-interactive-display}, like clicking an @samp{irc://}-style
|
||||
@acronym{URL} (@pxref{URL}).
|
||||
|
||||
@lisp
|
||||
(defun my-erc-interactive-display-buffer (buffer action)
|
||||
"Pop to BUFFER when running \\[erc-tls], clicking a link, etc."
|
||||
(when-let ((alist (cdr action))
|
||||
(found (alist-get 'erc-interactive-display alist)))
|
||||
(if (eq found 'erc-tls)
|
||||
(pop-to-buffer-same-window buffer action)
|
||||
(pop-to-buffer buffer action))))
|
||||
|
||||
(setopt erc-interactive-display #'my-erc-interactive-display-buffer)
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
Observe that ERC supplies the names of buffer-display options as
|
||||
@var{action} alist keys and pairs them with contextual constants, like
|
||||
the symbols @samp{erc-tls} or @samp{url}, the full lineup of which are
|
||||
listed below.
|
||||
|
||||
In this second example, the user writes three predicates that somewhat
|
||||
resemble the ``@code{display-buffer}-like'' function above. These too
|
||||
look for @var{action} alist keys sharing the names of buffer-display
|
||||
options (and, in one case, a module's minor mode).
|
||||
|
||||
@lisp
|
||||
(defun my-erc-disp-entry-p (_ action)
|
||||
(memq (cdr (or (assq 'erc-buffer-display action)
|
||||
(assq 'erc-interactive-display action)))
|
||||
'(erc-tls url)))
|
||||
|
||||
(defun my-erc-disp-query-p (_ action)
|
||||
(or (eq (cdr (assq 'erc-interactive-display action)) '/QUERY)
|
||||
(and (eq (cdr (assq 'erc-receive-query-display action)) 'PRIVMSG)
|
||||
(member (erc-default-target) '("bob" "alice")))))
|
||||
|
||||
(defun my-erc-disp-chan-p (_ action)
|
||||
(or (assq 'erc-autojoin-mode action)
|
||||
(and (memq (cdr (assq 'erc-buffer-display alist)) 'JOIN)
|
||||
(member (erc-default-target) '("#emacs" "#fsf")))))
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
You'll notice we ignore the @var{buffer} parameter of these predicates
|
||||
because ERC ensures that @var{buffer} is already current (which is why
|
||||
we can freely call @code{erc-default-target}). Note also that we
|
||||
cheat a little by treating the @var{action} parameter like an alist
|
||||
when it's really a cons of one or more functions and an alist.
|
||||
|
||||
@noindent
|
||||
To complement our predicates, we set all three buffer-display options
|
||||
referenced in their @var{action}-alist lookups to
|
||||
@code{display-buffer}. This tells ERC to defer to that function in
|
||||
the display contexts covered by these options.
|
||||
|
||||
@lisp
|
||||
(setopt erc-buffer-display #'display-buffer
|
||||
erc-interactive-display #'display-buffer
|
||||
erc-receive-query-display #'display-buffer
|
||||
;;
|
||||
erc-auto-reconnect-display 'bury)
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
The last option above just tells ERC to avoid any buffer-display
|
||||
machinery when auto-reconnecting. (For historical reasons, ERC's
|
||||
buffer-display options use the term ``bury'' to mean ``ignore'' rather
|
||||
than @code{bury-buffer}.)
|
||||
|
||||
Finally, we compose our predicates into @code{buffer-match-p}
|
||||
conditions and pair them with various well known @code{display-buffer}
|
||||
action functions and action-alist members.
|
||||
|
||||
@lisp
|
||||
(setopt display-buffer-alist
|
||||
|
||||
;; Create new frame with M-x erc-tls RET or (erc-tls ...)
|
||||
'(((and (major-mode . erc-mode) my-erc-disp-entry-p)
|
||||
display-buffer-pop-up-frame
|
||||
(reusable-frames . visible))
|
||||
|
||||
;; Show important chans and queries in a split.
|
||||
((and (major-mode . erc-mode)
|
||||
(or my-erc-disp-chan-p my-erc-disp-query-p))
|
||||
display-buffer-pop-up-window)
|
||||
|
||||
;; Ignore everything else.
|
||||
((major-mode . erc-mode)
|
||||
display-buffer-no-window
|
||||
(allow-no-window . t))))
|
||||
@end lisp
|
||||
|
||||
@noindent
|
||||
Of course, we could just as well set our buffer-display options to one
|
||||
or more homespun functions instead of bothering with
|
||||
@code{display-buffer-alist} at all (in what would make for a more
|
||||
complicated version of our first example). But perhaps we already
|
||||
have a growing menagerie of similar predicates and like to keep
|
||||
everything in one place in our @file{init.el}.
|
||||
|
||||
@subsubheading Action alist items
|
||||
|
||||
@table @asis
|
||||
@item Option-based keys:
|
||||
All keys are symbols, as are values, unless otherwise noted.
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{erc-buffer-display}
|
||||
@itemize @minus
|
||||
@item @samp{JOIN}
|
||||
@item @samp{NOTICE}
|
||||
@item @samp{PRIVMSG}
|
||||
@item @samp{erc} (entry point called non-interactively)
|
||||
@item @samp{erc-tls}
|
||||
@end itemize
|
||||
|
||||
@item @code{erc-interactive-display}
|
||||
@itemize @minus
|
||||
@item @samp{/QUERY}
|
||||
@item @samp{/JOIN}
|
||||
@item @samp{/RECONNECT}
|
||||
@item @samp{url} (hyperlink clicked)
|
||||
@item @samp{erc} (entry point called interactively)
|
||||
@item @samp{erc-tls}
|
||||
@end itemize
|
||||
|
||||
@item @code{erc-receive-query-display}
|
||||
@itemize @minus
|
||||
@item @samp{NOTICE}
|
||||
@item @samp{PRIVMSG}
|
||||
@end itemize
|
||||
|
||||
@item @code{erc-auto-reconnect-display}
|
||||
@itemize @minus
|
||||
@item something non-@code{nil}
|
||||
@end itemize
|
||||
@end itemize
|
||||
|
||||
@item Module-based (minor-mode) keys:
|
||||
|
||||
@itemize @bullet
|
||||
@item @code{erc-autojoin-mode}
|
||||
@itemize @minus
|
||||
@item channel name as a string, e.g., @code{"#chan"}
|
||||
@end itemize
|
||||
@end itemize
|
||||
@end table
|
||||
|
||||
@node Options
|
||||
@section Options
|
||||
|
|
|
|||
16
etc/ERC-NEWS
16
etc/ERC-NEWS
|
|
@ -37,7 +37,7 @@ decade overdue, this is no longer the case. Other UX improvements in
|
|||
this area aim to make the process of connecting interactively slightly
|
||||
more streamlined and less repetitive, even for veteran users.
|
||||
|
||||
** Revised buffer-display handling for interactive commands.
|
||||
** Revised buffer-display handling.
|
||||
A point of friction for new users and one only just introduced with
|
||||
ERC 5.5 has been the lack of visual feedback when first connecting via
|
||||
M-x erc or when issuing a "/JOIN" command at the prompt. As explained
|
||||
|
|
@ -56,7 +56,19 @@ reported as being difficult to discover and remember. When the latter
|
|||
option (now known as 'erc-receive-query-display') is nil, ERC uses
|
||||
'erc-join-buffer' in its place, much like it does for
|
||||
'erc-interactive-display'. The old nil behavior can still be gotten
|
||||
via the new compatibility flag 'erc-receive-query-display-defer'.
|
||||
via the new compatibility flag 'erc-receive-query-display-defer'. The
|
||||
relatively new option 'erc-reconnect-display' has likewise been
|
||||
renamed, this time for clarity, to 'erc-auto-reconnect-display'.
|
||||
|
||||
This release also introduces a few subtleties affecting the display of
|
||||
new or reassociated buffers. One involves buffers that already occupy
|
||||
the selected window. ERC now treats these as deserving of an implicit
|
||||
'bury'. An escape hatch for this and most other baked-in behaviors is
|
||||
now available in the form of a new type variant recognized by all such
|
||||
options. That is, users can now specify their own function to
|
||||
exercise full control over nearly all buffer-display related
|
||||
decisions. See the newly expanded doc strings of 'erc-buffer-display'
|
||||
and friends, as well as Info node '(erc) display-buffer', for details.
|
||||
|
||||
** Setting a module's mode variable via Customize earns a warning.
|
||||
Trying and failing to activate a module via its minor mode's Custom
|
||||
|
|
|
|||
|
|
@ -101,6 +101,8 @@
|
|||
(eval-when-compile (require 'cl-lib))
|
||||
(require 'erc-common)
|
||||
|
||||
(defvar erc--called-as-input-p)
|
||||
(defvar erc--display-context)
|
||||
(defvar erc--target)
|
||||
(defvar erc--user-from-nick-function)
|
||||
(defvar erc-channel-list)
|
||||
|
|
@ -304,7 +306,7 @@ function `erc-server-process-alive' instead.")
|
|||
"Timer that resets `erc--server-last-reconnect-count' to zero.
|
||||
Becomes non-nil in all server buffers when an IRC connection is
|
||||
first \"established\" and carries out its duties
|
||||
`erc-reconnect-display-timeout' seconds later.")
|
||||
`erc-auto-reconnect-display-timeout' seconds later.")
|
||||
|
||||
(defvar-local erc--server-last-reconnect-count 0
|
||||
"Snapshot of reconnect count when the connection was established.")
|
||||
|
|
@ -957,7 +959,7 @@ EVENT is the message received from the closed connection process."
|
|||
(erc--server-last-reconnect-display-reset (current-buffer)))
|
||||
|
||||
(defun erc--server-last-reconnect-display-reset (buffer)
|
||||
"Deactivate `erc-reconnect-display'."
|
||||
"Deactivate `erc-auto-reconnect-display'."
|
||||
(when (buffer-live-p buffer)
|
||||
(with-current-buffer buffer
|
||||
(when erc--server-reconnect-display-timer
|
||||
|
|
@ -1684,6 +1686,12 @@ add things to `%s' instead."
|
|||
parsed 'notice 'active
|
||||
'INVITE ?n nick ?u login ?h host ?c chnl)))))
|
||||
|
||||
(cl-defmethod erc--server-determine-join-display-context (_channel alist)
|
||||
"Determine `erc--display-context' for JOINs."
|
||||
(if (assq 'erc-buffer-display alist)
|
||||
alist
|
||||
`((erc-buffer-display . JOIN) ,@alist)))
|
||||
|
||||
(define-erc-response-handler (JOIN)
|
||||
"Handle join messages."
|
||||
nil
|
||||
|
|
@ -1698,7 +1706,11 @@ add things to `%s' instead."
|
|||
(let* ((str (cond
|
||||
;; If I have joined a channel
|
||||
((erc-current-nick-p nick)
|
||||
(when (setq buffer (erc--open-target chnl))
|
||||
(let ((erc--display-context
|
||||
(erc--server-determine-join-display-context
|
||||
chnl erc--display-context)))
|
||||
(setq buffer (erc--open-target chnl)))
|
||||
(when buffer
|
||||
(set-buffer buffer)
|
||||
(with-suppressed-warnings
|
||||
((obsolete erc-add-default-channel))
|
||||
|
|
@ -1887,6 +1899,8 @@ add things to `%s' instead."
|
|||
(noticep (string= cmd "NOTICE"))
|
||||
;; S.B. downcase *both* tgt and current nick
|
||||
(privp (erc-current-nick-p tgt))
|
||||
(erc--display-context `((erc-buffer-display . ,(intern cmd))
|
||||
,@erc--display-context))
|
||||
s buffer
|
||||
fnick)
|
||||
(setf (erc-response.contents parsed) msg)
|
||||
|
|
@ -1901,6 +1915,8 @@ add things to `%s' instead."
|
|||
(and erc-ensure-target-buffer-on-privmsg
|
||||
(or erc-receive-query-display
|
||||
erc-join-buffer)))))
|
||||
(push `(erc-receive-query-display . ,(intern cmd))
|
||||
erc--display-context)
|
||||
(setq buffer (erc--open-target nick)))
|
||||
;; A channel buffer has been killed but is still joined.
|
||||
(when erc-ensure-target-buffer-on-privmsg
|
||||
|
|
@ -2486,6 +2502,17 @@ See `erc-display-server-message'." nil
|
|||
parsed
|
||||
(erc-response.contents parsed)))
|
||||
|
||||
(define-erc-response-handler (471)
|
||||
"ERR_CHANNELISFULL: channel full." nil
|
||||
(erc-display-message parsed '(notice error) nil 's471
|
||||
?c (cadr (erc-response.command-args parsed))
|
||||
?s (erc-response.contents parsed)))
|
||||
|
||||
(define-erc-response-handler (473)
|
||||
"ERR_INVITEONLYCHAN: channel invitation only." nil
|
||||
(erc-display-message parsed '(notice error) nil 's473
|
||||
?c (cadr (erc-response.command-args parsed))))
|
||||
|
||||
(define-erc-response-handler (474)
|
||||
"Banned from channel errors." nil
|
||||
(erc-display-message parsed '(notice error) nil
|
||||
|
|
@ -2499,6 +2526,7 @@ See `erc-display-server-message'." nil
|
|||
?c (cadr (erc-response.command-args parsed)))
|
||||
(when erc-prompt-for-channel-key
|
||||
(let ((channel (cadr (erc-response.command-args parsed)))
|
||||
(erc--called-as-input-p t)
|
||||
(key (read-from-minibuffer
|
||||
(format "Channel %s is mode +k. Enter key (RET to cancel): "
|
||||
(cadr (erc-response.command-args parsed))))))
|
||||
|
|
@ -2567,7 +2595,7 @@ See `erc-display-error-notice'." nil
|
|||
;; 200 201 202 203 204 205 206 208 209 211 212 213
|
||||
;; 214 215 216 217 218 219 241 242 243 244 249 261
|
||||
;; 262 302 342 351 407 409 411 413 414 415
|
||||
;; 423 424 436 441 443 444 467 471 472 473 KILL)
|
||||
;; 423 424 436 441 443 444 467 472 KILL)
|
||||
;; nil nil
|
||||
;; (ignore proc parsed))
|
||||
|
||||
|
|
|
|||
|
|
@ -44,11 +44,23 @@
|
|||
((add-hook 'erc-after-connect #'erc-autojoin-channels)
|
||||
(add-hook 'erc-nickserv-identified-hook #'erc-autojoin-after-ident)
|
||||
(add-hook 'erc-server-JOIN-functions #'erc-autojoin-add)
|
||||
(add-hook 'erc-server-PART-functions #'erc-autojoin-remove))
|
||||
(add-hook 'erc-server-PART-functions #'erc-autojoin-remove)
|
||||
(add-hook 'erc-server-405-functions #'erc-join--remove-requested-channel)
|
||||
(add-hook 'erc-server-471-functions #'erc-join--remove-requested-channel)
|
||||
(add-hook 'erc-server-473-functions #'erc-join--remove-requested-channel)
|
||||
(add-hook 'erc-server-474-functions #'erc-join--remove-requested-channel)
|
||||
(add-hook 'erc-server-475-functions #'erc-join--remove-requested-channel))
|
||||
((remove-hook 'erc-after-connect #'erc-autojoin-channels)
|
||||
(remove-hook 'erc-nickserv-identified-hook #'erc-autojoin-after-ident)
|
||||
(remove-hook 'erc-server-JOIN-functions #'erc-autojoin-add)
|
||||
(remove-hook 'erc-server-PART-functions #'erc-autojoin-remove)))
|
||||
(remove-hook 'erc-server-PART-functions #'erc-autojoin-remove)
|
||||
(remove-hook 'erc-server-405-functions #'erc-join--remove-requested-channel)
|
||||
(remove-hook 'erc-server-471-functions #'erc-join--remove-requested-channel)
|
||||
(remove-hook 'erc-server-473-functions #'erc-join--remove-requested-channel)
|
||||
(remove-hook 'erc-server-474-functions #'erc-join--remove-requested-channel)
|
||||
(remove-hook 'erc-server-475-functions #'erc-join--remove-requested-channel)
|
||||
(erc-buffer-do (lambda ()
|
||||
(kill-local-variable 'erc-join--requested-channels)))))
|
||||
|
||||
(defcustom erc-autojoin-channels-alist nil
|
||||
"Alist of channels to autojoin on IRC networks.
|
||||
|
|
@ -138,6 +150,28 @@ network or a network ID). Return nil on failure."
|
|||
(string-match-p candidate (or erc-server-announced-name
|
||||
erc-session-server)))))
|
||||
|
||||
(defvar-local erc-join--requested-channels nil
|
||||
"List of channels for which an outgoing JOIN was sent.")
|
||||
|
||||
;; Assume users will update their `erc-autojoin-channels-alist' when
|
||||
;; encountering errors, like a 475 ERR_BADCHANNELKEY.
|
||||
(defun erc-join--remove-requested-channel (_ parsed)
|
||||
"Remove channel from `erc-join--requested-channels'."
|
||||
(when-let ((channel (cadr (erc-response.command-args parsed)))
|
||||
((member channel erc-join--requested-channels)))
|
||||
(setq erc-join--requested-channels
|
||||
(delete channel erc-join--requested-channels)))
|
||||
nil)
|
||||
|
||||
(cl-defmethod erc--server-determine-join-display-context
|
||||
(channel alist &context (erc-autojoin-mode (eql t)))
|
||||
"Add item to `erc-display-context' ALIST if CHANNEL was autojoined."
|
||||
(when (member channel erc-join--requested-channels)
|
||||
(setq erc-join--requested-channels
|
||||
(delete channel erc-join--requested-channels))
|
||||
(push (cons 'erc-autojoin-mode channel) alist))
|
||||
(cl-call-next-method channel alist))
|
||||
|
||||
(defun erc-autojoin--join ()
|
||||
;; This is called in the server buffer
|
||||
(pcase-dolist (`(,name . ,channels) erc-autojoin-channels-alist)
|
||||
|
|
@ -146,6 +180,7 @@ network or a network ID). Return nil on failure."
|
|||
(let ((buf (erc-get-buffer chan erc-server-process)))
|
||||
(unless (and buf (with-current-buffer buf
|
||||
(erc--current-buffer-joined-p)))
|
||||
(push chan erc-join--requested-channels)
|
||||
(erc-server-join-channel nil chan)))))))
|
||||
|
||||
(defun erc-autojoin-after-ident (_network _nick)
|
||||
|
|
|
|||
206
lisp/erc/erc.el
206
lisp/erc/erc.el
|
|
@ -1553,9 +1553,26 @@ Defaults to the server buffer."
|
|||
"IRC port to use for encrypted connections if it cannot be \
|
||||
detected otherwise.")
|
||||
|
||||
(defconst erc--buffer-display-choices
|
||||
`(choice (const :tag "Use value of `erc-buffer-display'" nil)
|
||||
(const :tag "Split window and select" window)
|
||||
(const :tag "Split window but don't select" window-noselect)
|
||||
(const :tag "New frame" frame)
|
||||
(const :tag "Don't display" bury)
|
||||
(const :tag "Use current window" buffer)
|
||||
(choice :tag "Defer to a display function"
|
||||
(function-item display-buffer)
|
||||
(function-item pop-to-buffer)
|
||||
(function :tag "User-defined")))
|
||||
"Common choices for buffer-display options.")
|
||||
|
||||
(defvaralias 'erc-join-buffer 'erc-buffer-display)
|
||||
(defcustom erc-buffer-display 'bury
|
||||
"How to display a newly created ERC buffer.
|
||||
This determines ERC's baseline, \"catch-all\" buffer-display
|
||||
behavior. It takes a backseat to more specific options, like
|
||||
`erc-interactive-display', `erc-auto-reconnect-display', and
|
||||
`erc-receive-query-display'.
|
||||
|
||||
The available choices are:
|
||||
|
||||
|
|
@ -1564,17 +1581,34 @@ The available choices are:
|
|||
`frame' - in another frame,
|
||||
`bury' - bury it in a new buffer,
|
||||
`buffer' - in place of the current buffer,
|
||||
DISPLAY-FUNCTION - a `display-buffer'-like function
|
||||
|
||||
See related options `erc-interactive-display',
|
||||
`erc-reconnect-display', and `erc-receive-query-display'."
|
||||
Here, DISPLAY-FUNCTION should accept a buffer and an ACTION of
|
||||
the kind described by the Info node `(elisp) Choosing Window'.
|
||||
At times, ERC may add hints about the calling context to the
|
||||
ACTION's alist. Keys are symbols such as user options, like
|
||||
`erc-buffer-display', or module minor modes, like
|
||||
`erc-autojoin-mode'. Values are non-nil constants specific to
|
||||
each. For this particular option, possible values include the
|
||||
symbols
|
||||
|
||||
`JOIN', `PRIVMSG', `NOTICE', `erc', and `erc-tls'.
|
||||
|
||||
The first three signify IRC commands received from the server and
|
||||
the rest entry-point commands responsible for the connection.
|
||||
When dealing with the latter two, users may prefer to set this
|
||||
option to `bury' and instead call DISPLAY-FUNCTION directly
|
||||
on (server) buffers returned by these entry points because the
|
||||
context leading to their creation is plainly obvious. For
|
||||
additional details, see the Info node `(erc) display-buffer'.
|
||||
|
||||
Note that when the selected window already shows the current
|
||||
buffer, ERC pretends this option's value is `bury' unless the
|
||||
variable `erc-skip-displaying-selected-window-buffer' is nil or
|
||||
the value of this option is DISPLAY-FUNCTION."
|
||||
:package-version '(ERC . "5.5")
|
||||
:group 'erc-buffers
|
||||
:type '(choice (const :tag "Split window and select" window)
|
||||
(const :tag "Split window, don't select" window-noselect)
|
||||
(const :tag "New frame" frame)
|
||||
(const :tag "Bury in new buffer" bury)
|
||||
(const :tag "Use current buffer" buffer)
|
||||
(const :tag "Use current buffer" t)))
|
||||
:type (cons 'choice (nthcdr 2 erc--buffer-display-choices)))
|
||||
|
||||
(defvaralias 'erc-query-display 'erc-interactive-display)
|
||||
(defcustom erc-interactive-display 'window
|
||||
|
|
@ -1583,38 +1617,58 @@ This affects commands like /QUERY and /JOIN when issued
|
|||
interactively at the prompt. It does not apply when calling a
|
||||
handler for such a command, like `erc-cmd-JOIN', from lisp code.
|
||||
See `erc-buffer-display' for a full description of available
|
||||
values."
|
||||
values.
|
||||
|
||||
When the value is a user-provided function, ERC may inject a hint
|
||||
about the invocation context as an extra item in the \"action
|
||||
alist\" included as part of the second argument. The item's key
|
||||
is the symbol `erc-interactive-display' and its value one of
|
||||
|
||||
`/QUERY', `/JOIN', `/RECONNECT', `url', `erc', or `erc-tls'.
|
||||
|
||||
All are symbols indicating an inciting user action, such as the
|
||||
issuance of a slash command, the clicking of a URL hyperlink, or
|
||||
the invocation of an entry-point command. See Info node `(erc)
|
||||
display-buffer' for more."
|
||||
:package-version '(ERC . "5.6") ; FIXME sync on release
|
||||
:group 'erc-buffers
|
||||
:type '(choice (const :tag "Use value of `erc-buffer-display'" nil)
|
||||
(const :tag "Split window and select" window)
|
||||
(const :tag "Split window, don't select" window-noselect)
|
||||
(const :tag "New frame" frame)
|
||||
(const :tag "Bury new and don't display existing" bury)
|
||||
(const :tag "Use current buffer" buffer)))
|
||||
:type erc--buffer-display-choices)
|
||||
|
||||
(defcustom erc-reconnect-display nil
|
||||
"How and whether to display a channel buffer when auto-reconnecting.
|
||||
This only affects automatic reconnections and is ignored, like
|
||||
all other buffer-display options, when issuing a /RECONNECT or
|
||||
successfully reinvoking `erc-tls' with similar arguments. See
|
||||
`erc-buffer-display' for a description of possible values."
|
||||
(defvaralias 'erc-reconnect-display 'erc-auto-reconnect-display)
|
||||
(defcustom erc-auto-reconnect-display nil
|
||||
"How to display a channel buffer when automatically reconnecting.
|
||||
ERC ignores this option when a user issues a /RECONNECT or
|
||||
successfully reinvokes `erc-tls' with similar arguments to those
|
||||
from the prior connection. See `erc-buffer-display' for a
|
||||
description of possible values.
|
||||
|
||||
When the value is function, ERC may inject a hint about the
|
||||
calling context as an extra item in the alist making up the tail
|
||||
of the second, \"action\" argument. The item's key is the symbol
|
||||
`erc-auto-reconnect-display' and its value something non-nil."
|
||||
:package-version '(ERC . "5.5")
|
||||
:group 'erc-buffers
|
||||
:type '(choice (const :tag "Use value of `erc-buffer-display'" nil)
|
||||
(const :tag "Split window and select" window)
|
||||
(const :tag "Split window, don't select" window-noselect)
|
||||
(const :tag "New frame" frame)
|
||||
(const :tag "Bury in new buffer" bury)
|
||||
(const :tag "Use current buffer" buffer)))
|
||||
:type erc--buffer-display-choices)
|
||||
|
||||
(defcustom erc-reconnect-display-timeout 10
|
||||
"Duration `erc-reconnect-display' remains active.
|
||||
(defcustom erc-auto-reconnect-display-timeout 10
|
||||
"Duration `erc-auto-reconnect-display' remains active.
|
||||
The countdown starts on MOTD and is canceled early by any
|
||||
\"slash\" command."
|
||||
:package-version '(ERC . "5.6") ; FIXME sync on release
|
||||
:type 'integer
|
||||
:group 'erc-buffers)
|
||||
|
||||
(defcustom erc-reconnect-display-server-buffers nil
|
||||
"Apply buffer-display options to server buffers when reconnecting.
|
||||
By default, ERC does not consider `erc-auto-reconnect-display'
|
||||
for server buffers when automatically reconnecting, nor does it
|
||||
consider `erc-interactive-display' when users issue a /RECONNECT.
|
||||
Enabling this tells ERC to always display server buffers
|
||||
according to those options."
|
||||
:package-version '(ERC . "5.6") ; FIXME sync on release
|
||||
:type 'boolean
|
||||
:group 'erc-buffers)
|
||||
|
||||
(defcustom erc-frame-alist nil
|
||||
"Alist of frame parameters for creating erc frames.
|
||||
A value of nil means to use `default-frame-alist'."
|
||||
|
|
@ -1824,9 +1878,8 @@ server connection, or nil which means all open connections."
|
|||
|
||||
(defalias 'erc-buffer-do 'erc-buffer-filter
|
||||
"Call FUNCTION in all ERC buffers or only those for PROC.
|
||||
Expect users to prefer this alias to `erc-buffer-filter' in cases
|
||||
where the latter would only be called for effect and its return
|
||||
value thrown away.
|
||||
Expect to be preferred over `erc-buffer-filter' in cases where
|
||||
the return value goes unused.
|
||||
|
||||
\(fn FUNCTION &optional PROC)")
|
||||
|
||||
|
|
@ -2094,12 +2147,43 @@ anything about the dependency's implementation.")
|
|||
(defvar erc--setup-buffer-hook nil
|
||||
"Internal hook for module setup involving windows and frames.")
|
||||
|
||||
(defvar erc--display-context nil
|
||||
"Extra action alist items passed to `display-buffer'.
|
||||
Non-nil when a user specifies a custom display action for certain
|
||||
buffer-display options, like `erc-auto-reconnect-display'. ERC
|
||||
pairs the option's symbol with a context-dependent value and adds
|
||||
the entry to the user-provided alist when calling `pop-to-buffer'
|
||||
or `display-buffer'.")
|
||||
|
||||
(defvar erc-skip-displaying-selected-window-buffer t
|
||||
"Whether to forgo showing a buffer that's already being displayed.
|
||||
But only in the selected window. This is intended as a crutch
|
||||
for non-user third-party code that might be slow to adopt the
|
||||
`display-buffer' function variant available to all buffer-display
|
||||
options starting in ERC 5.6. Users with rare requirements, like
|
||||
wanting to change the window buffer to something other than the
|
||||
one being processed, should see the Info node `(erc)
|
||||
display-buffer'.")
|
||||
(make-obsolete 'erc-show-already-displayed-buffer
|
||||
"non-nil behavior to be made permanent" "30.1")
|
||||
|
||||
(defvar-local erc--display-buffer-overriding-action nil
|
||||
"The value of `display-buffer-overriding-action' when non-nil.
|
||||
Influences the displaying of new or reassociated ERC buffers.
|
||||
Reserved for use by built-in modules.")
|
||||
|
||||
(defun erc-setup-buffer (buffer)
|
||||
"Consults `erc-join-buffer' to find out how to display `BUFFER'."
|
||||
(pcase (if (zerop (erc-with-server-buffer
|
||||
erc--server-last-reconnect-count))
|
||||
erc-join-buffer
|
||||
(or erc-reconnect-display erc-join-buffer))
|
||||
(or erc-auto-reconnect-display erc-join-buffer))
|
||||
((and (pred functionp) disp-fn (let context erc--display-context))
|
||||
(unless (zerop erc--server-last-reconnect-count)
|
||||
(push '(erc-auto-reconnect-display . t) context))
|
||||
(funcall disp-fn buffer (cons nil context)))
|
||||
((guard (and erc-skip-displaying-selected-window-buffer
|
||||
(eq (window-buffer) buffer))))
|
||||
('window
|
||||
(if (active-minibuffer-window)
|
||||
(display-buffer buffer)
|
||||
|
|
@ -2292,13 +2376,18 @@ Returns the buffer for the given server or channel."
|
|||
(erc-update-mode-line))
|
||||
|
||||
;; Now display the buffer in a window as per user wishes.
|
||||
(unless (eq buffer old-buffer)
|
||||
(when (eq buffer old-buffer) (cl-assert (and connect (not target))))
|
||||
(unless (and (not erc-reconnect-display-server-buffers)
|
||||
(eq buffer old-buffer))
|
||||
(when erc-log-p
|
||||
;; we can't log to debug buffer, it may not exist yet
|
||||
(message "erc: old buffer %s, switching to %s"
|
||||
old-buffer buffer))
|
||||
(erc-setup-buffer buffer)
|
||||
(run-hooks 'erc--setup-buffer-hook))
|
||||
(let ((display-buffer-overriding-action
|
||||
(or erc--display-buffer-overriding-action
|
||||
display-buffer-overriding-action)))
|
||||
(erc-setup-buffer buffer)
|
||||
(run-hooks 'erc--setup-buffer-hook)))
|
||||
|
||||
buffer))
|
||||
|
||||
|
|
@ -2410,6 +2499,8 @@ With prefix arg, also prompt for user and full name."
|
|||
env)
|
||||
(when erc-interactive-display
|
||||
(push `(erc-join-buffer . ,erc-interactive-display) env))
|
||||
(when erc--display-context
|
||||
(push `(erc--display-context . ,erc--display-context) env))
|
||||
(when opener
|
||||
(push `(erc-server-connect-function . ,opener) env))
|
||||
(when (and passwd (string= "" passwd))
|
||||
|
|
@ -2471,7 +2562,12 @@ for the values of the other parameters.
|
|||
See `erc-tls' for the meaning of ID.
|
||||
|
||||
\(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME ID)"
|
||||
(interactive (erc-select-read-args))
|
||||
(interactive (let ((erc--display-context `((erc-interactive-display . erc)
|
||||
,@erc--display-context)))
|
||||
(erc-select-read-args)))
|
||||
(unless (assq 'erc--display-context --interactive-env--)
|
||||
(push '(erc--display-context . ((erc-buffer-display . erc)))
|
||||
--interactive-env--))
|
||||
(erc--with-entrypoint-environment --interactive-env--
|
||||
(erc-open server port nick full-name t password nil nil nil nil user id)))
|
||||
|
||||
|
|
@ -2536,8 +2632,11 @@ CLIENT-CERTIFICATE, this parameter cannot be specified
|
|||
interactively.
|
||||
|
||||
\(fn &key SERVER PORT NICK USER PASSWORD FULL-NAME CLIENT-CERTIFICATE ID)"
|
||||
(interactive (let ((erc-default-port erc-default-port-tls))
|
||||
(erc-select-read-args)))
|
||||
(interactive
|
||||
(let ((erc-default-port erc-default-port-tls)
|
||||
(erc--display-context `((erc-interactive-display . erc-tls)
|
||||
,@erc--display-context)))
|
||||
(erc-select-read-args)))
|
||||
;; Bind `erc-server-connect-function' to `erc-open-tls-stream'
|
||||
;; around `erc-open' when a non-default value hasn't been specified
|
||||
;; by the user or the interactive form. And don't bother checking
|
||||
|
|
@ -2546,6 +2645,9 @@ interactively.
|
|||
(not (eq erc-server-connect-function #'erc-open-network-stream)))
|
||||
(push '(erc-server-connect-function . erc-open-tls-stream)
|
||||
--interactive-env--))
|
||||
(unless (assq 'erc--display-context --interactive-env--)
|
||||
(push '(erc--display-context . ((erc-buffer-display . erc-tls)))
|
||||
--interactive-env--))
|
||||
(erc--with-entrypoint-environment --interactive-env--
|
||||
(erc-open server port nick full-name t password
|
||||
nil nil nil client-certificate user id)))
|
||||
|
|
@ -3769,7 +3871,10 @@ were most recently invited. See also `invitation'."
|
|||
(sn (erc-extract-nick (erc-response.sender parsed)))
|
||||
((erc-nick-equal-p sn (erc-current-nick)))
|
||||
(erc-join-buffer (or erc-interactive-display
|
||||
erc-join-buffer)))
|
||||
erc-join-buffer))
|
||||
(erc--display-context `((erc-interactive-display
|
||||
. /JOIN)
|
||||
,@erc--display-context)))
|
||||
(run-hook-with-args-until-success
|
||||
'erc-server-JOIN-functions proc parsed)
|
||||
t))))
|
||||
|
|
@ -4153,7 +4258,9 @@ on the value of `erc-interactive-display'."
|
|||
;; currently broken, evil hack to display help anyway
|
||||
;(erc-delete-query))))
|
||||
(signal 'wrong-number-of-arguments '(erc-cmd-QUERY 0)))
|
||||
(let ((erc-join-buffer erc-interactive-display))
|
||||
(let ((erc-join-buffer erc-interactive-display)
|
||||
(erc--display-context `((erc-interactive-display . /QUERY)
|
||||
,@erc--display-context)))
|
||||
(erc-with-server-buffer
|
||||
(erc--open-target user))))
|
||||
|
||||
|
|
@ -4273,6 +4380,9 @@ the message given by REASON."
|
|||
|
||||
(defun erc--cmd-reconnect ()
|
||||
(let ((buffer (erc-server-buffer))
|
||||
(erc-join-buffer erc-interactive-display)
|
||||
(erc--display-context `((erc-interactive-display . /RECONNECT)
|
||||
,@erc--display-context))
|
||||
(process nil))
|
||||
(unless (buffer-live-p buffer)
|
||||
(setq buffer (current-buffer)))
|
||||
|
|
@ -4937,13 +5047,7 @@ compatibility flag `erc-receive-query-display-defer' to nil. Use
|
|||
:package-version '(ERC . "5.6")
|
||||
:group 'erc-buffers
|
||||
:group 'erc-query
|
||||
:type '(choice (const :tag "Defer to value of `erc-buffer-display'" nil)
|
||||
(const :tag "Split window and select" window)
|
||||
(const :tag "Split window, don't select" window-noselect)
|
||||
(const :tag "New frame" frame)
|
||||
(const :tag "Bury in new buffer" bury)
|
||||
(const :tag "Use current buffer" buffer)
|
||||
(const :tag "Use current buffer" t)))
|
||||
:type erc--buffer-display-choices)
|
||||
|
||||
(defvar erc-receive-query-display-defer t
|
||||
"How to interpret a null `erc-receive-query-display'.
|
||||
|
|
@ -5389,7 +5493,7 @@ Set user modes and run `erc-after-connect' hook."
|
|||
(setq erc--server-last-reconnect-count erc-server-reconnect-count
|
||||
erc-server-reconnect-count 0)
|
||||
(setq erc--server-reconnect-display-timer
|
||||
(run-at-time erc-reconnect-display-timeout nil
|
||||
(run-at-time erc-auto-reconnect-display-timeout nil
|
||||
#'erc--server-last-reconnect-display-reset
|
||||
(current-buffer)))
|
||||
(add-hook 'erc-disconnected-hook
|
||||
|
|
@ -7769,6 +7873,8 @@ All windows are opened in the current frame."
|
|||
(s463 . "Your host isn't among the privileged")
|
||||
(s464 . "Password incorrect")
|
||||
(s465 . "You are banned from this server")
|
||||
(s471 . "Max occupancy for channel %c exceeded: %s")
|
||||
(s473 . "Channel %c is invitation only")
|
||||
(s474 . "You can't join %c because you're banned (+b)")
|
||||
(s475 . "You must specify the correct channel key (+k) to join %c")
|
||||
(s481 . "Permission Denied - You're not an IRC operator")
|
||||
|
|
@ -7970,6 +8076,8 @@ 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))
|
||||
(erc--display-context `((erc-interactive-display . url)
|
||||
,@erc--display-context))
|
||||
(server-buffer
|
||||
;; Viable matches may slip through the cracks for unknown
|
||||
;; networks. Additional passes could likely improve things.
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@
|
|||
|
||||
(eval-when-compile (require 'erc-join))
|
||||
|
||||
;; These first couple `erc-reconnect-display' tests used to live in
|
||||
;; erc-scenarios-base-reconnect but have since been renamed.
|
||||
;; These first couple `erc-auto-reconnect-display' tests used to live
|
||||
;; in erc-scenarios-base-reconnect but have since been renamed.
|
||||
|
||||
(defun erc-scenarios-base-buffer-display--reconnect-common
|
||||
(assert-server assert-chan assert-rest)
|
||||
|
|
@ -80,11 +80,11 @@
|
|||
:tags '(:expensive-test)
|
||||
(should (eq erc-buffer-display 'bury))
|
||||
(should (eq erc-interactive-display 'window))
|
||||
(should-not erc-reconnect-display)
|
||||
(should-not erc-auto-reconnect-display)
|
||||
|
||||
(let ((erc-buffer-display 'window)
|
||||
(erc-interactive-display 'buffer)
|
||||
(erc-reconnect-display 'bury))
|
||||
(erc-auto-reconnect-display 'bury))
|
||||
|
||||
(erc-scenarios-base-buffer-display--reconnect-common
|
||||
|
||||
|
|
@ -104,7 +104,7 @@
|
|||
;; A manual /JOIN command tells ERC we're done auto-reconnecting
|
||||
(with-current-buffer "FooNet" (erc-scenarios-common-say "/JOIN #spam"))
|
||||
|
||||
(ert-info ("#spam ignores `erc-reconnect-display'")
|
||||
(ert-info ("#spam ignores `erc-auto-reconnect-display'")
|
||||
;; Uses `erc-interactive-display' instead.
|
||||
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
|
||||
(should (eq (window-buffer) (get-buffer "#spam")))
|
||||
|
|
@ -115,10 +115,10 @@
|
|||
:tags '(:expensive-test)
|
||||
(should (eq erc-buffer-display 'bury))
|
||||
(should (eq erc-interactive-display 'window))
|
||||
(should-not erc-reconnect-display)
|
||||
(should-not erc-auto-reconnect-display)
|
||||
|
||||
(let ((erc-buffer-display 'window-noselect)
|
||||
(erc-reconnect-display 'bury)
|
||||
(erc-auto-reconnect-display 'bury)
|
||||
(erc-interactive-display 'buffer))
|
||||
(erc-scenarios-base-buffer-display--reconnect-common
|
||||
|
||||
|
|
@ -155,7 +155,7 @@
|
|||
(should (eq (window-buffer) (get-buffer "bob")))
|
||||
(should (frame-root-window-p (selected-window)))))
|
||||
|
||||
(ert-info ("Newly joined chan ignores `erc-reconnect-display'")
|
||||
(ert-info ("Newly joined chan ignores `erc-auto-reconnect-display'")
|
||||
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
|
||||
(should (eq (window-buffer) (get-buffer "bob")))
|
||||
(should-not (frame-root-window-p (selected-window)))
|
||||
|
|
@ -165,13 +165,13 @@
|
|||
:tags '(:expensive-test)
|
||||
(should (eq erc-buffer-display 'bury))
|
||||
(should (eq erc-interactive-display 'window))
|
||||
(should (eq erc-reconnect-display-timeout 10))
|
||||
(should-not erc-reconnect-display)
|
||||
(should (eq erc-auto-reconnect-display-timeout 10))
|
||||
(should-not erc-auto-reconnect-display)
|
||||
|
||||
(let ((erc-buffer-display 'window-noselect)
|
||||
(erc-reconnect-display 'bury)
|
||||
(erc-auto-reconnect-display 'bury)
|
||||
(erc-interactive-display 'buffer)
|
||||
(erc-reconnect-display-timeout 0.5))
|
||||
(erc-auto-reconnect-display-timeout 0.5))
|
||||
(erc-scenarios-base-buffer-display--reconnect-common
|
||||
#'ignore #'ignore ; These two are identical to the previous test.
|
||||
|
||||
|
|
@ -188,10 +188,10 @@
|
|||
(erc-d-t-wait-for 1 (null erc--server-reconnect-display-timer))
|
||||
(erc-cmd-JOIN "#spam")))
|
||||
|
||||
(ert-info ("Newly joined chan ignores `erc-reconnect-display'")
|
||||
(ert-info ("Newly joined chan ignores `erc-auto-reconnect-display'")
|
||||
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))
|
||||
(should (eq (window-buffer) (messages-buffer)))
|
||||
;; If `erc-reconnect-display-timeout' were left alone, this
|
||||
;; If `erc-auto-reconnect-display-timeout' were left alone, this
|
||||
;; would be (frame-root-window-p #<window 1 on *scratch*>).
|
||||
(should-not (frame-root-window-p (selected-window)))
|
||||
(should (eq (current-buffer) (window-buffer (next-window))))))))))
|
||||
|
|
|
|||
66
test/lisp/erc/erc-scenarios-join-display-context.el
Normal file
66
test/lisp/erc/erc-scenarios-join-display-context.el
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
;;; erc-scenarios-join-display-context.el --- buffer-display autojoin ctx -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
;; This file is part of GNU Emacs.
|
||||
|
||||
;; GNU Emacs is free software: you can redistribute it and/or modify
|
||||
;; it under the terms of the GNU General Public License as published by
|
||||
;; the Free Software Foundation, either version 3 of the License, or
|
||||
;; (at your option) any later version.
|
||||
|
||||
;; GNU Emacs is distributed in the hope that it will be useful,
|
||||
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
;; GNU General Public License for more details.
|
||||
|
||||
;; You should have received a copy of the GNU General Public License
|
||||
;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Commentary:
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ert-x)
|
||||
(eval-and-compile
|
||||
(let ((load-path (cons (ert-resource-directory) load-path)))
|
||||
(require 'erc-scenarios-common)))
|
||||
|
||||
(ert-deftest erc-scenarios-join-display-context--errors ()
|
||||
:tags '(:expensive-test)
|
||||
(erc-scenarios-common-with-cleanup
|
||||
((erc-scenarios-common-dialog "join/buffer-display")
|
||||
(erc-server-flood-penalty 0.1)
|
||||
(dumb-server (erc-d-run "localhost" t 'mode-context))
|
||||
(port (process-contact dumb-server :service))
|
||||
(erc-buffer-display (lambda (buf action)
|
||||
(when (equal
|
||||
(alist-get 'erc-autojoin-mode action)
|
||||
"#chan")
|
||||
(pop-to-buffer buf))))
|
||||
(erc-autojoin-channels-alist '((foonet "#chan" "#spam" "#foo")))
|
||||
(expect (erc-d-t-make-expecter)))
|
||||
|
||||
(ert-info ("Connect without password")
|
||||
(with-current-buffer (erc :server "127.0.0.1"
|
||||
:port port
|
||||
:nick "tester"
|
||||
:full-name "tester")
|
||||
(should (string= (buffer-name) (format "127.0.0.1:%d" port)))
|
||||
;; FIXME test for effect rather than inspecting interval variables.
|
||||
(erc-d-t-wait-for 10 (equal erc-join--requested-channels
|
||||
'("#foo" "#spam" "#chan")))
|
||||
(funcall expect 10 "Max occupancy for channel #spam exceeded")
|
||||
(funcall expect 10 "Channel #foo is invitation only")))
|
||||
|
||||
(ert-info ("New #chan buffer displayed in new window")
|
||||
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
|
||||
(should (eq (window-buffer) (current-buffer)))
|
||||
(funcall expect 10 "#chan was created on")))
|
||||
|
||||
;; FIXME find a less dishonest way to do this than inspecting
|
||||
;; interval variables.
|
||||
(ert-info ("Ensure channels no longer tracked")
|
||||
(should-not erc-join--requested-channels))))
|
||||
|
||||
;;; erc-scenarios-join-display-context.el ends here
|
||||
|
|
@ -427,8 +427,9 @@
|
|||
(should (looking-at-p (regexp-quote "*** Welcome"))))
|
||||
|
||||
(ert-info ("Reconnect")
|
||||
(erc-open "localhost" 6667 "tester" "Tester" nil
|
||||
"fake" nil "#chan" proc nil "user" nil)
|
||||
(with-current-buffer (erc-server-buffer)
|
||||
(erc-open "localhost" 6667 "tester" "Tester" nil
|
||||
"fake" nil "#chan" proc nil "user" nil))
|
||||
(should-not (get-buffer "#chan<2>")))
|
||||
|
||||
(ert-info ("Existing prompt respected")
|
||||
|
|
@ -512,6 +513,50 @@
|
|||
(dolist (b '("server" "other" "#chan" "#foo" "#fake"))
|
||||
(kill-buffer b))))
|
||||
|
||||
(ert-deftest erc-setup-buffer--custom-action ()
|
||||
(erc-mode)
|
||||
(erc-tests--set-fake-server-process "sleep" "1")
|
||||
(setq erc--server-last-reconnect-count 0)
|
||||
(let ((owin (selected-window))
|
||||
(obuf (window-buffer))
|
||||
(mbuf (messages-buffer))
|
||||
calls)
|
||||
(cl-letf (((symbol-function 'switch-to-buffer) ; regression
|
||||
(lambda (&rest r) (push (cons 'switch-to-buffer r) calls)))
|
||||
((symbol-function 'erc--test-fun)
|
||||
(lambda (&rest r) (push (cons 'erc--test-fun r) calls)))
|
||||
((symbol-function 'display-buffer)
|
||||
(lambda (&rest r) (push (cons 'display-buffer r) calls))))
|
||||
|
||||
;; Baseline
|
||||
(let ((erc-join-buffer 'bury))
|
||||
(erc-setup-buffer mbuf)
|
||||
(should-not calls))
|
||||
|
||||
(should-not erc--display-context)
|
||||
|
||||
;; `display-buffer'
|
||||
(let ((erc--display-context '((erc-buffer-display . 1)))
|
||||
(erc-join-buffer 'erc--test-fun))
|
||||
(erc-setup-buffer mbuf)
|
||||
(should (equal `(erc--test-fun ,mbuf (nil (erc-buffer-display . 1)))
|
||||
(pop calls)))
|
||||
(should-not calls))
|
||||
|
||||
;; `pop-to-buffer' with `erc-auto-reconnect-display'
|
||||
(let* ((erc--server-last-reconnect-count 1)
|
||||
(erc--display-context '((erc-buffer-display . 1)))
|
||||
(erc-auto-reconnect-display 'erc--test-fun))
|
||||
(erc-setup-buffer mbuf)
|
||||
(should (equal `(erc--test-fun ,mbuf
|
||||
(nil (erc-auto-reconnect-display . t)
|
||||
(erc-buffer-display . 1)))
|
||||
(pop calls)))
|
||||
(should-not calls)))
|
||||
|
||||
(should (eq owin (selected-window)))
|
||||
(should (eq obuf (window-buffer)))))
|
||||
|
||||
(ert-deftest erc-lurker-maybe-trim ()
|
||||
(let (erc-lurker-trim-nicks
|
||||
(erc-lurker-ignore-chars "_`"))
|
||||
|
|
@ -1537,14 +1582,18 @@
|
|||
(erc-join-buffer . window))))))
|
||||
|
||||
(ert-info ("Switches to TLS when URL is ircs://")
|
||||
(should (equal (ert-simulate-keys "ircs://irc.gnu.org\r\r\r\r"
|
||||
(erc-select-read-args))
|
||||
(list :server "irc.gnu.org"
|
||||
:port 6697
|
||||
:nick (user-login-name)
|
||||
'&interactive-env
|
||||
'((erc-server-connect-function . erc-open-tls-stream)
|
||||
(erc-join-buffer . window))))))
|
||||
(let ((erc--display-context '((erc-interactive-display . erc))))
|
||||
(should (equal (ert-simulate-keys "ircs://irc.gnu.org\r\r\r\r"
|
||||
(erc-select-read-args))
|
||||
(list :server "irc.gnu.org"
|
||||
:port 6697
|
||||
:nick (user-login-name)
|
||||
'&interactive-env
|
||||
'((erc-server-connect-function
|
||||
. erc-open-tls-stream)
|
||||
(erc--display-context
|
||||
. ((erc-interactive-display . erc)))
|
||||
(erc-join-buffer . window)))))))
|
||||
|
||||
(setq-local erc-interactive-display nil) ; cheat to save space
|
||||
|
||||
|
|
@ -1624,6 +1673,7 @@
|
|||
((symbol-function 'erc-open)
|
||||
(lambda (&rest r)
|
||||
(push `((erc-join-buffer ,erc-join-buffer)
|
||||
(erc--display-context ,@erc--display-context)
|
||||
(erc-server-connect-function
|
||||
,erc-server-connect-function))
|
||||
env)
|
||||
|
|
@ -1636,6 +1686,7 @@
|
|||
nil nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer bury)
|
||||
(erc--display-context (erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
(ert-info ("Full")
|
||||
|
|
@ -1652,6 +1703,7 @@
|
|||
"bob:changeme" nil nil nil t "bobo" GNU.org)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer bury)
|
||||
(erc--display-context (erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
;; Values are often nil when called by lisp code, which leads to
|
||||
|
|
@ -1671,6 +1723,7 @@
|
|||
"bob:changeme" nil nil nil nil "bobo" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer bury)
|
||||
(erc--display-context (erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
(ert-info ("Interactive")
|
||||
|
|
@ -1681,6 +1734,8 @@
|
|||
nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer window)
|
||||
(erc--display-context
|
||||
(erc-interactive-display . erc-tls))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
(ert-info ("Custom connect function")
|
||||
|
|
@ -1691,6 +1746,8 @@
|
|||
nil nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer bury)
|
||||
(erc--display-context
|
||||
(erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function my-connect-func))))))
|
||||
|
||||
(ert-info ("Advised default function overlooked") ; intentional
|
||||
|
|
@ -1702,6 +1759,7 @@
|
|||
nil nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer bury)
|
||||
(erc--display-context (erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function erc-open-tls-stream))))
|
||||
(advice-remove 'erc-server-connect-function 'erc-tests--erc-tls))
|
||||
|
||||
|
|
@ -1715,6 +1773,8 @@
|
|||
'("irc.libera.chat" 6697 "tester" "unknown" t
|
||||
nil nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env) `((erc-join-buffer bury)
|
||||
(erc--display-context
|
||||
(erc-buffer-display . erc-tls))
|
||||
(erc-server-connect-function ,f))))
|
||||
(advice-remove 'erc-server-connect-function
|
||||
'erc-tests--erc-tls)))))))
|
||||
|
|
@ -1729,6 +1789,7 @@
|
|||
((symbol-function 'erc-open)
|
||||
(lambda (&rest r)
|
||||
(push `((erc-join-buffer ,erc-join-buffer)
|
||||
(erc--display-context ,@erc--display-context)
|
||||
(erc-server-connect-function
|
||||
,erc-server-connect-function))
|
||||
env)
|
||||
|
|
@ -1741,8 +1802,9 @@
|
|||
'("irc.libera.chat" 6697 "tester" "unknown" t nil
|
||||
nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer window) (erc-server-connect-function
|
||||
erc-open-tls-stream)))))
|
||||
'((erc-join-buffer window)
|
||||
(erc--display-context (erc-interactive-display . erc))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
(ert-info ("Nick supplied, decline TLS upgrade")
|
||||
(ert-simulate-keys "\r\rdummy\r\rn\r"
|
||||
|
|
@ -1752,6 +1814,7 @@
|
|||
nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer window)
|
||||
(erc--display-context (erc-interactive-display . erc))
|
||||
(erc-server-connect-function
|
||||
erc-open-network-stream))))))))
|
||||
|
||||
|
|
@ -1762,6 +1825,7 @@
|
|||
((symbol-function 'erc-open)
|
||||
(lambda (&rest r)
|
||||
(push `((erc-join-buffer ,erc-join-buffer)
|
||||
(erc--display-context ,@erc--display-context)
|
||||
(erc-server-connect-function
|
||||
,erc-server-connect-function))
|
||||
env)
|
||||
|
|
@ -1776,6 +1840,7 @@
|
|||
nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer window)
|
||||
(erc--display-context (erc-interactive-display . erc))
|
||||
(erc-server-connect-function erc-open-tls-stream)))))
|
||||
|
||||
(ert-info ("Selects entry that doesn't support TLS")
|
||||
|
|
@ -1787,6 +1852,7 @@
|
|||
nil nil nil nil "user" nil)))
|
||||
(should (equal (pop env)
|
||||
'((erc-join-buffer window)
|
||||
(erc--display-context (erc-interactive-display . erc))
|
||||
(erc-server-connect-function
|
||||
erc-open-network-stream))))))))
|
||||
|
||||
|
|
|
|||
38
test/lisp/erc/resources/join/buffer-display/mode-context.eld
Normal file
38
test/lisp/erc/resources/join/buffer-display/mode-context.eld
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
;; -*- mode: lisp-data; -*-
|
||||
((nick 1 "NICK tester"))
|
||||
((user 1 "USER user 0 * :tester")
|
||||
(0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
|
||||
(0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.8.0")
|
||||
(0.00 ":irc.foonet.org 003 tester :This server was created Tue, 24 May 2022 05:28:42 UTC")
|
||||
(0.00 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.8.0 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
|
||||
(0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX KICKLEN=390 :are supported by this server")
|
||||
(0.01 ":irc.foonet.org 005 tester MAXLIST=beI:60 MAXTARGETS=4 MODES MONITOR=100 NETWORK=foonet NICKLEN=32 PREFIX=(qaohv)~&@%+ STATUSMSG=~&@%+ TARGMAX=NAMES:1,LIST:1,KICK:,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
|
||||
(0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
|
||||
(0.00 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)")
|
||||
(0.00 ":irc.foonet.org 252 tester 0 :IRC Operators online")
|
||||
(0.00 ":irc.foonet.org 253 tester 0 :unregistered connections")
|
||||
(0.00 ":irc.foonet.org 254 tester 2 :channels formed")
|
||||
(0.00 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers")
|
||||
(0.00 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4")
|
||||
(0.00 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4")
|
||||
(0.00 ":irc.foonet.org 422 tester :MOTD File is missing"))
|
||||
|
||||
((mode 6 "MODE tester +i")
|
||||
(0.00 ":irc.foonet.org 221 tester +i")
|
||||
(0.00 ":irc.foonet.org NOTICE tester :This server is in debug mode and is logging all user I/O. If you do not wish for everything you send to be readable by the server owner(s), please disconnect.")
|
||||
(0.02 ":irc.foonet.org 221 tester +i"))
|
||||
|
||||
((join-chan 10 "JOIN #chan")
|
||||
(0.03 ":tester!~u@w9rfqveugz722.irc JOIN #chan"))
|
||||
|
||||
((~mode-chan 10 "MODE #chan")
|
||||
(0.01 ":irc.foonet.org 353 tester = #chan :@tester")
|
||||
(0.00 ":irc.foonet.org 366 tester #chan :End of NAMES list")
|
||||
(0.01 ":irc.foonet.org 324 tester #chan +nt")
|
||||
(0.03 ":irc.foonet.org 329 tester #chan 1653370308"))
|
||||
|
||||
((~join-spam 10 "JOIN #spam")
|
||||
(0.03 ":irc.foonet.org 471 tester #spam :Cannot join channel (+l)"))
|
||||
|
||||
((~join-foo 10 "JOIN #foo")
|
||||
(0.03 ":irc.foonet.org 473 tester #foo :Cannot join channel (+i)"))
|
||||
Loading…
Add table
Add a link
Reference in a new issue