diff options
| author | F. Jason Park | 2023-12-23 12:46:33 -0800 |
|---|---|---|
| committer | F. Jason Park | 2023-12-27 21:32:25 -0800 |
| commit | 65735efdca017f2ec0aa1022b7e82f68fbe0084d (patch) | |
| tree | 9e00293e01aff32fe594e43ba484a702429a0a26 | |
| parent | 8f571769e155a214ae2f9f760dd179b687d9982e (diff) | |
| download | emacs-65735efdca017f2ec0aa1022b7e82f68fbe0084d.tar.gz emacs-65735efdca017f2ec0aa1022b7e82f68fbe0084d.zip | |
Improve multi-window erc-keep-place-indicator-mode
* lisp/erc/erc-goodies.el (erc-keep-place-indicator-follow): Describe
condition causing an indicator update.
(erc--keep-place-indicator-on-window-configuration-change,
erc--keep-place-indicator-on-window-buffer-change): Rename former to
latter, add required WINDOW parameter, and don't move indicator if
buffer appears in multiple windows. Also, don't bother checking
whether either buffer is a mini because the manual says window change
functions don't run for minibuffer replacements.
(erc--keep-place-indicator-setup): Hook on
`window-buffer-change-functions' instead of
`window-configuration-change-hook'.
(erc-keep-place-mode, erc-keep-place-disable): Remove member from
`window-buffer-change-functions' instead of
`window-configuration-change-hook'.
(erc-keep-place): Use `visible' FRAME arg of `get-buffer-window'.
Don't twiddle `window-prev-buffers' when
`erc-keep-place-indicator-mode' is non-nil. This feature was
originally introduced by bug#59943.
* test/lisp/erc/erc-goodies-tests.el
(erc-goodies-tests--assert-kp-indicator-on,
erc-goodies-tests--assert-kp-indicator-off): Update hook name.
* test/lisp/erc/erc-scenarios-keep-place-indicator.el: New file.
* test/lisp/erc/resources/keep-place/follow.eld: New file.
| -rw-r--r-- | lisp/erc/erc-goodies.el | 54 | ||||
| -rw-r--r-- | test/lisp/erc/erc-goodies-tests.el | 4 | ||||
| -rw-r--r-- | test/lisp/erc/erc-scenarios-keep-place-indicator.el | 134 | ||||
| -rw-r--r-- | test/lisp/erc/resources/keep-place/follow.eld | 73 |
4 files changed, 244 insertions, 21 deletions
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el index e10f047b187..9d385b628dc 100644 --- a/lisp/erc/erc-goodies.el +++ b/lisp/erc/erc-goodies.el | |||
| @@ -300,7 +300,10 @@ A value of t means \"all\" ERC buffers." | |||
| 300 | 300 | ||
| 301 | (defcustom erc-keep-place-indicator-follow nil | 301 | (defcustom erc-keep-place-indicator-follow nil |
| 302 | "Whether to sync visual kept place to window's top when reading. | 302 | "Whether to sync visual kept place to window's top when reading. |
| 303 | For use with `erc-keep-place-indicator-mode'." | 303 | For use with `erc-keep-place-indicator-mode'. When enabled, the |
| 304 | indicator updates when the last window displaying the same buffer | ||
| 305 | switches away, but only if the indicator resides earlier in the | ||
| 306 | buffer than the window's start." | ||
| 304 | :group 'erc | 307 | :group 'erc |
| 305 | :package-version '(ERC . "5.6") | 308 | :package-version '(ERC . "5.6") |
| 306 | :type 'boolean) | 309 | :type 'boolean) |
| @@ -328,17 +331,26 @@ For use with `erc-keep-place-indicator-mode'." | |||
| 328 | (defvar-local erc--keep-place-indicator-overlay nil | 331 | (defvar-local erc--keep-place-indicator-overlay nil |
| 329 | "Overlay for `erc-keep-place-indicator-mode'.") | 332 | "Overlay for `erc-keep-place-indicator-mode'.") |
| 330 | 333 | ||
| 331 | (defun erc--keep-place-indicator-on-window-configuration-change () | 334 | (defun erc--keep-place-indicator-on-window-buffer-change (window) |
| 332 | "Maybe sync `erc--keep-place-indicator-overlay'. | 335 | "Maybe sync `erc--keep-place-indicator-overlay'. |
| 333 | Specifically, do so unless switching to or from another window in | 336 | Do so only when switching to a new buffer in the same window if |
| 334 | the active frame." | 337 | the replaced buffer is no longer visible in another window and |
| 335 | (when erc-keep-place-indicator-follow | 338 | its `window-start' at the time of switching is strictly greater |
| 336 | (unless (or (minibuffer-window-active-p (minibuffer-window)) | 339 | than the indicator's position." |
| 337 | (eq (window-old-buffer) (current-buffer))) | 340 | (when-let ((erc-keep-place-indicator-follow) |
| 338 | (when (< (overlay-end erc--keep-place-indicator-overlay) | 341 | ((eq window (selected-window))) |
| 339 | (window-start) | 342 | (old-buffer (window-old-buffer window)) |
| 340 | erc-insert-marker) | 343 | ((buffer-live-p old-buffer)) |
| 341 | (erc-keep-place-move (window-start)))))) | 344 | ((not (eq old-buffer (current-buffer)))) |
| 345 | (ov (buffer-local-value 'erc--keep-place-indicator-overlay | ||
| 346 | old-buffer)) | ||
| 347 | ((not (get-buffer-window old-buffer 'visible))) | ||
| 348 | (prev (assq old-buffer (window-prev-buffers window))) | ||
| 349 | (old-start (nth 1 prev)) | ||
| 350 | (old-inmkr (buffer-local-value 'erc-insert-marker old-buffer)) | ||
| 351 | ((< (overlay-end ov) old-start old-inmkr))) | ||
| 352 | (with-current-buffer old-buffer | ||
| 353 | (erc-keep-place-move old-start)))) | ||
| 342 | 354 | ||
| 343 | (defun erc--keep-place-indicator-setup () | 355 | (defun erc--keep-place-indicator-setup () |
| 344 | "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'." | 356 | "Initialize buffer for maintaining `erc--keep-place-indicator-overlay'." |
| @@ -347,8 +359,8 @@ the active frame." | |||
| 347 | erc--keep-place-indicator-overlay (make-overlay 0 0)) | 359 | erc--keep-place-indicator-overlay (make-overlay 0 0)) |
| 348 | (add-hook 'erc-keep-place-mode-hook | 360 | (add-hook 'erc-keep-place-mode-hook |
| 349 | #'erc--keep-place-indicator-on-global-module nil t) | 361 | #'erc--keep-place-indicator-on-global-module nil t) |
| 350 | (add-hook 'window-configuration-change-hook | 362 | (add-hook 'window-buffer-change-functions |
| 351 | #'erc--keep-place-indicator-on-window-configuration-change nil t) | 363 | #'erc--keep-place-indicator-on-window-buffer-change 40 t) |
| 352 | (when-let* (((memq erc-keep-place-indicator-style '(t arrow))) | 364 | (when-let* (((memq erc-keep-place-indicator-style '(t arrow))) |
| 353 | (ov-property (if (zerop (fringe-columns 'left)) | 365 | (ov-property (if (zerop (fringe-columns 'left)) |
| 354 | 'after-string | 366 | 'after-string |
| @@ -368,7 +380,11 @@ the active frame." | |||
| 368 | "Buffer-local `keep-place' with fringe arrow and/or highlighted face. | 380 | "Buffer-local `keep-place' with fringe arrow and/or highlighted face. |
| 369 | Play nice with global module `keep-place' but don't depend on it. | 381 | Play nice with global module `keep-place' but don't depend on it. |
| 370 | Expect that users may want different combinations of `keep-place' | 382 | Expect that users may want different combinations of `keep-place' |
| 371 | and `keep-place-indicator' in different buffers." | 383 | and `keep-place-indicator' in different buffers. Unlike global |
| 384 | `keep-place', when `switch-to-buffer-preserve-window-point' is | ||
| 385 | enabled, don't forcibly sync point in all windows where buffer | ||
| 386 | has previously been shown because that defeats the purpose of | ||
| 387 | having a placeholder." | ||
| 372 | ((cond (erc-keep-place-mode) | 388 | ((cond (erc-keep-place-mode) |
| 373 | ((memq 'keep-place erc-modules) | 389 | ((memq 'keep-place erc-modules) |
| 374 | (erc-keep-place-mode +1)) | 390 | (erc-keep-place-mode +1)) |
| @@ -382,8 +398,8 @@ and `keep-place-indicator' in different buffers." | |||
| 382 | (erc-keep-place-indicator-mode -1))) | 398 | (erc-keep-place-indicator-mode -1))) |
| 383 | ((when erc--keep-place-indicator-overlay | 399 | ((when erc--keep-place-indicator-overlay |
| 384 | (delete-overlay erc--keep-place-indicator-overlay)) | 400 | (delete-overlay erc--keep-place-indicator-overlay)) |
| 385 | (remove-hook 'window-configuration-change-hook | 401 | (remove-hook 'window-buffer-change-functions |
| 386 | #'erc--keep-place-indicator-on-window-configuration-change t) | 402 | #'erc--keep-place-indicator-on-window-buffer-change t) |
| 387 | (remove-hook 'erc-keep-place-mode-hook | 403 | (remove-hook 'erc-keep-place-mode-hook |
| 388 | #'erc--keep-place-indicator-on-global-module t) | 404 | #'erc--keep-place-indicator-on-global-module t) |
| 389 | (remove-hook 'erc-insert-pre-hook #'erc-keep-place t) | 405 | (remove-hook 'erc-insert-pre-hook #'erc-keep-place t) |
| @@ -450,13 +466,13 @@ For use with `keep-place-indicator' module." | |||
| 450 | (forward-line -1) | 466 | (forward-line -1) |
| 451 | (when erc-keep-place-indicator-mode | 467 | (when erc-keep-place-indicator-mode |
| 452 | (unless (or (minibuffer-window-active-p (selected-window)) | 468 | (unless (or (minibuffer-window-active-p (selected-window)) |
| 453 | (and (frame-visible-p (selected-frame)) | 469 | (get-buffer-window nil 'visible)) |
| 454 | (get-buffer-window (current-buffer) (selected-frame)))) | ||
| 455 | (erc-keep-place-move nil))) | 470 | (erc-keep-place-move nil))) |
| 456 | ;; if `switch-to-buffer-preserve-window-point' is set, | 471 | ;; if `switch-to-buffer-preserve-window-point' is set, |
| 457 | ;; we cannot rely on point being saved, and must commit | 472 | ;; we cannot rely on point being saved, and must commit |
| 458 | ;; it to window-prev-buffers. | 473 | ;; it to window-prev-buffers. |
| 459 | (when switch-to-buffer-preserve-window-point | 474 | (when (and switch-to-buffer-preserve-window-point |
| 475 | (not erc-keep-place-indicator-mode)) | ||
| 460 | (dolist (frame (frame-list)) | 476 | (dolist (frame (frame-list)) |
| 461 | (walk-window-tree | 477 | (walk-window-tree |
| 462 | (lambda (window) | 478 | (lambda (window) |
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el index cdf861e2018..ca02089eb7c 100644 --- a/test/lisp/erc/erc-goodies-tests.el +++ b/test/lisp/erc/erc-goodies-tests.el | |||
| @@ -247,7 +247,7 @@ | |||
| 247 | 247 | ||
| 248 | (defun erc-goodies-tests--assert-kp-indicator-on () | 248 | (defun erc-goodies-tests--assert-kp-indicator-on () |
| 249 | (should erc--keep-place-indicator-overlay) | 249 | (should erc--keep-place-indicator-overlay) |
| 250 | (should (local-variable-p 'window-configuration-change-hook)) | 250 | (should (local-variable-p 'window-buffer-change-functions)) |
| 251 | (should window-configuration-change-hook) | 251 | (should window-configuration-change-hook) |
| 252 | (should (memq 'erc-keep-place erc-insert-pre-hook)) | 252 | (should (memq 'erc-keep-place erc-insert-pre-hook)) |
| 253 | (should (eq erc-keep-place-mode | 253 | (should (eq erc-keep-place-mode |
| @@ -255,7 +255,7 @@ | |||
| 255 | 255 | ||
| 256 | (defun erc-goodies-tests--assert-kp-indicator-off () | 256 | (defun erc-goodies-tests--assert-kp-indicator-off () |
| 257 | (should-not (local-variable-p 'erc-insert-pre-hook)) | 257 | (should-not (local-variable-p 'erc-insert-pre-hook)) |
| 258 | (should-not (local-variable-p 'window-configuration-change-hook)) | 258 | (should-not (local-variable-p 'window-buffer-change-functions)) |
| 259 | (should-not erc--keep-place-indicator-overlay)) | 259 | (should-not erc--keep-place-indicator-overlay)) |
| 260 | 260 | ||
| 261 | (defun erc-goodies-tests--kp-indicator-populate () | 261 | (defun erc-goodies-tests--kp-indicator-populate () |
diff --git a/test/lisp/erc/erc-scenarios-keep-place-indicator.el b/test/lisp/erc/erc-scenarios-keep-place-indicator.el new file mode 100644 index 00000000000..7566288066e --- /dev/null +++ b/test/lisp/erc/erc-scenarios-keep-place-indicator.el | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | ;;; erc-scenarios-keep-place-indicator.el --- erc-keep-place-indicator-mode -*- lexical-binding: t -*- | ||
| 2 | |||
| 3 | ;; Copyright (C) 2023 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; This file is part of GNU Emacs. | ||
| 6 | |||
| 7 | ;; GNU Emacs is free software: you can redistribute it and/or modify | ||
| 8 | ;; it under the terms of the GNU General Public License as published by | ||
| 9 | ;; the Free Software Foundation, either version 3 of the License, or | ||
| 10 | ;; (at your option) any later version. | ||
| 11 | |||
| 12 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 13 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 14 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 15 | ;; GNU General Public License for more details. | ||
| 16 | |||
| 17 | ;; You should have received a copy of the GNU General Public License | ||
| 18 | ;; along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. | ||
| 19 | |||
| 20 | ;;; Code: | ||
| 21 | |||
| 22 | (require 'ert-x) | ||
| 23 | (eval-and-compile | ||
| 24 | (let ((load-path (cons (ert-resource-directory) load-path))) | ||
| 25 | (require 'erc-scenarios-common))) | ||
| 26 | |||
| 27 | (require 'erc-goodies) | ||
| 28 | |||
| 29 | ;; This test shows that the indicator does not update when at least | ||
| 30 | ;; one window remains. When the last window showing a buffer switches | ||
| 31 | ;; away, the indicator is updated if it's earlier in the buffer. | ||
| 32 | (ert-deftest erc-scenarios-keep-place-indicator--follow () | ||
| 33 | :tags `(:expensive-test | ||
| 34 | ,@(and (getenv "ERC_TESTS_GRAPHICAL") '(:erc--graphical))) | ||
| 35 | (when (version< emacs-version "29") (ert-skip "Times out")) | ||
| 36 | ;; XXX verify that this continues to be the case ^. | ||
| 37 | |||
| 38 | (should-not erc-scrolltobottom-all) | ||
| 39 | (should-not erc-scrolltobottom-mode) | ||
| 40 | (should-not erc-keep-place-mode) | ||
| 41 | |||
| 42 | (erc-scenarios-common-with-noninteractive-in-term | ||
| 43 | ((erc-scenarios-common-dialog "keep-place") | ||
| 44 | (dumb-server (erc-d-run "localhost" t 'follow)) | ||
| 45 | (port (process-contact dumb-server :service)) | ||
| 46 | (erc-modules `( keep-place-indicator scrolltobottom fill-wrap | ||
| 47 | ,@erc-modules)) | ||
| 48 | (erc-keep-place-indicator-follow t) | ||
| 49 | (erc-scrolltobottom-all t) | ||
| 50 | (erc-server-flood-penalty 0.1) | ||
| 51 | (erc-autojoin-channels-alist '((foonet "#chan" "#spam"))) | ||
| 52 | (expect (erc-d-t-make-expecter))) | ||
| 53 | |||
| 54 | (ert-info ("Connect") | ||
| 55 | (with-current-buffer (erc :server "127.0.0.1" | ||
| 56 | :port port | ||
| 57 | :full-name "tester" | ||
| 58 | :nick "tester" | ||
| 59 | :user "tester") | ||
| 60 | (funcall expect 10 "debug mode"))) | ||
| 61 | |||
| 62 | (with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan")) | ||
| 63 | (set-window-buffer nil (current-buffer)) | ||
| 64 | (delete-other-windows) | ||
| 65 | (split-window-below) | ||
| 66 | (funcall expect 10 "<bob> tester, welcome!") | ||
| 67 | (recenter 0) | ||
| 68 | (other-window 1) | ||
| 69 | (funcall expect 10 "<alice> tester, welcome!") | ||
| 70 | (recenter 0) | ||
| 71 | (should (= 2 (length (window-list)))) | ||
| 72 | |||
| 73 | (ert-info ("Last window to switch away has point earlier in buffer") | ||
| 74 | ;; Lower window, with point later in buffer, switches away first. | ||
| 75 | (switch-to-buffer (erc-d-t-wait-for 10 (get-buffer "#spam"))) ; lower | ||
| 76 | (other-window 1) | ||
| 77 | (switch-to-buffer "#spam") ; upper | ||
| 78 | (erc-scenarios-common-say "one") | ||
| 79 | (funcall expect 10 "Ay, the heads") | ||
| 80 | |||
| 81 | ;; Overlay has moved to upper window start. | ||
| 82 | (switch-to-buffer "#chan") | ||
| 83 | (redisplay) ; force overlay to update | ||
| 84 | (save-excursion | ||
| 85 | (goto-char (window-point)) | ||
| 86 | (should (looking-back (rx "<bob> tester, welcome!"))) | ||
| 87 | (should (= (pos-bol) (window-start))) | ||
| 88 | (should (= (overlay-start erc--keep-place-indicator-overlay) | ||
| 89 | (pos-bol)))) | ||
| 90 | ;; Lower window is still centered at start. | ||
| 91 | (other-window 1) | ||
| 92 | (switch-to-buffer "#chan") | ||
| 93 | (save-excursion | ||
| 94 | (goto-char (window-point)) | ||
| 95 | (should (looking-back (rx "<alice> tester, welcome!"))) | ||
| 96 | (should (= (pos-bol) (window-start))))) | ||
| 97 | |||
| 98 | (ert-info ("Last window to switch away has point later in buffer") | ||
| 99 | ;; Lower window advances. | ||
| 100 | (funcall expect 10 "<bob> alice: Since you can cog") | ||
| 101 | (recenter 0) | ||
| 102 | (redisplay) ; force ^ to appear on first line | ||
| 103 | |||
| 104 | (other-window 1) ; upper still at indicator, swtiches first | ||
| 105 | (switch-to-buffer "#spam") | ||
| 106 | (other-window 1) | ||
| 107 | (switch-to-buffer "#spam") ; lower follows, speaks to sync | ||
| 108 | (erc-scenarios-common-say "two") | ||
| 109 | (funcall expect 10 "<bob> Cause they take") | ||
| 110 | |||
| 111 | ;; Upper switches back first, finds indicator gone. | ||
| 112 | (other-window 1) | ||
| 113 | (switch-to-buffer "#chan") | ||
| 114 | (save-excursion | ||
| 115 | (goto-char (window-point)) | ||
| 116 | (should (looking-back (rx "<bob> tester, welcome!"))) | ||
| 117 | (should (= (pos-bol) (window-start))) | ||
| 118 | (should (> (overlay-start erc--keep-place-indicator-overlay) | ||
| 119 | (pos-eol)))) | ||
| 120 | |||
| 121 | ;; Lower window follows, window-start preserved. | ||
| 122 | (other-window 1) | ||
| 123 | (switch-to-buffer "#chan") | ||
| 124 | (save-excursion | ||
| 125 | (goto-char (window-point)) | ||
| 126 | (should (looking-back (rx "you can cog"))) | ||
| 127 | (should (= (pos-bol) (window-start))) | ||
| 128 | (should (= (overlay-start erc--keep-place-indicator-overlay) | ||
| 129 | (pos-bol)))))) | ||
| 130 | |||
| 131 | (erc-keep-place-mode -1) | ||
| 132 | (erc-scrolltobottom-mode -1))) | ||
| 133 | |||
| 134 | ;;; erc-scenarios-keep-place-indicator.el ends here | ||
diff --git a/test/lisp/erc/resources/keep-place/follow.eld b/test/lisp/erc/resources/keep-place/follow.eld new file mode 100644 index 00000000000..e857c17175d --- /dev/null +++ b/test/lisp/erc/resources/keep-place/follow.eld | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | ;; -*- mode: lisp-data; -*- | ||
| 2 | ((nick 10 "NICK tester")) | ||
| 3 | ((user 10 "USER tester 0 * :tester") | ||
| 4 | (0.00 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester") | ||
| 5 | (0.01 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version ergo-v2.11.1") | ||
| 6 | (0.01 ":irc.foonet.org 003 tester :This server was created Tue, 26 Dec 2023 08:36:35 UTC") | ||
| 7 | (0.01 ":irc.foonet.org 004 tester irc.foonet.org ergo-v2.11.1 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv") | ||
| 8 | (0.00 ":irc.foonet.org 005 tester AWAYLEN=390 BOT=B CASEMAPPING=ascii CHANLIMIT=#:100 CHANMODES=Ibe,k,fl,CEMRUimnstu CHANNELLEN=64 CHANTYPES=# CHATHISTORY=1000 ELIST=U EXCEPTS EXTBAN=,m FORWARD=f INVEX :are supported by this server") | ||
| 9 | (0.01 ":irc.foonet.org 005 tester KICKLEN=390 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 UTF8ONLY WHOX :are supported by this server") | ||
| 10 | (0.01 ":irc.foonet.org 005 tester draft/CHATHISTORY=1000 :are supported by this server") | ||
| 11 | (0.01 ":irc.foonet.org 251 tester :There are 0 users and 4 invisible on 1 server(s)") | ||
| 12 | (0.01 ":irc.foonet.org 252 tester 0 :IRC Operators online") | ||
| 13 | (0.00 ":irc.foonet.org 253 tester 0 :unregistered connections") | ||
| 14 | (0.00 ":irc.foonet.org 254 tester 2 :channels formed") | ||
| 15 | (0.00 ":irc.foonet.org 255 tester :I have 4 clients and 0 servers") | ||
| 16 | (0.00 ":irc.foonet.org 265 tester 4 4 :Current local users 4, max 4") | ||
| 17 | (0.00 ":irc.foonet.org 266 tester 4 4 :Current global users 4, max 4") | ||
| 18 | (0.03 ":irc.foonet.org 422 tester :MOTD File is missing") | ||
| 19 | (0.01 ":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.")) | ||
| 20 | |||
| 21 | ((mode 10 "MODE tester +i")) | ||
| 22 | |||
| 23 | ((join 10 "JOIN #chan") | ||
| 24 | (0.01 ":irc.foonet.org 221 tester +i") | ||
| 25 | (0.01 ":tester!~u@p64eqfwvvbxrk.irc JOIN #chan") | ||
| 26 | (0.03 ":irc.foonet.org 353 tester = #chan :@fsbot bob alice tester") | ||
| 27 | (0.01 ":irc.foonet.org 366 tester #chan :End of NAMES list") | ||
| 28 | (0.00 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :tester, welcome!") | ||
| 29 | (0.01 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :tester, welcome!")) | ||
| 30 | |||
| 31 | ((join 10 "JOIN #spam") | ||
| 32 | (0.00 ":tester!~u@p64eqfwvvbxrk.irc JOIN #spam") | ||
| 33 | (0.06 ":irc.foonet.org 353 tester = #spam :@fsbot bob alice tester") | ||
| 34 | (0.01 ":irc.foonet.org 366 tester #spam :End of NAMES list") | ||
| 35 | (0.03 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #spam :tester, welcome!") | ||
| 36 | (0.01 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #spam :tester, welcome!")) | ||
| 37 | |||
| 38 | ((mode 10 "MODE #chan") | ||
| 39 | (0.00 ":irc.foonet.org 324 tester #chan +Cnt") | ||
| 40 | (0.02 ":irc.foonet.org 329 tester #chan 1703579802") | ||
| 41 | (0.02 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :bob: Madam, my lord is gone, for ever gone.") | ||
| 42 | (0.10 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :The kinder we, to give them thanks for nothing.")) | ||
| 43 | |||
| 44 | ((mode 10 "MODE #spam") | ||
| 45 | (0.00 ":irc.foonet.org 324 tester #spam +Cnt") | ||
| 46 | (0.02 ":irc.foonet.org 329 tester #spam 1703579805") | ||
| 47 | (0.02 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :Most manifest, and not denied by himself.") | ||
| 48 | (0.02 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: To bed, to bed: there's knocking at the gate. Come, come, come, come, give me your hand. What's done cannot be undone.") | ||
| 49 | (0.02 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :bob: And what I spake, I spake it to my face.") | ||
| 50 | (0.08 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: Since you can cog, I'll play no more with you.") | ||
| 51 | (0.06 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :bob: The little casket bring me hither.") | ||
| 52 | (0.01 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: Not to-night, good Iago: I have very poor and unhappy brains for drinking: I could well wish courtesy would invent some other custom of entertainment.") | ||
| 53 | (0.02 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :Yes, faith will I, Fridays and Saturdays and all.")) | ||
| 54 | |||
| 55 | ((privmsg 10 "PRIVMSG #spam :one") | ||
| 56 | (0.03 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :bob: This is the first truth that e'er thine own tongue was guilty of.") | ||
| 57 | (0.02 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: Drown the lamenting fool in sea-salt tears.") | ||
| 58 | |||
| 59 | ;; Insert some lines ^ before rendezvous, so #chan can update scrolltobottom. | ||
| 60 | (0.01 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #spam :Ay, the heads of the maids, or their maidenheads; take it in what sense thou wilt.") | ||
| 61 | |||
| 62 | (0.05 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: And work confusion on his enemies.") | ||
| 63 | (0.06 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :bob: Truly, she must be given, or the marriage is not lawful.")) | ||
| 64 | |||
| 65 | ((privmsg 10 "PRIVMSG #spam :two") | ||
| 66 | (0.02 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :To be whipped; and yet a better love than my master.") | ||
| 67 | (0.06 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :And duty in his service perishing.") | ||
| 68 | |||
| 69 | ;; Second check point. | ||
| 70 | (0.01 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #spam :Cause they take vengeance of such kind of men.") | ||
| 71 | |||
| 72 | (0.03 ":bob!~u@2q6ysndq32az6.irc PRIVMSG #chan :alice: No egma, no riddle, no l'envoy; no salve in the mail, sir. O! sir, plantain, a plain plantain: no l'envoy, no l'envoy: no salve, sir, but a plantain.") | ||
| 73 | (0.03 ":alice!~u@2q6ysndq32az6.irc PRIVMSG #chan :Signior Iachimo will not from it. Pray, let us follow 'em.")) | ||