Manage some text props for ERC insertion-hook members

* etc/ERC-NEWS: Mention that ERC only adds the text property
`cursor-sensor-functions' when `erc-echo-timestamps' is enabled.  Also
mention that date stamps are now inserted as separate messages.
* lisp/erc/erc-fill.el (erc-fill): Look for text prop `erc-cmd'
instead of `erc-command' and use helper utility to do so.
(erc-fill-static): Skip date stamps because this fill style leaves
them flush left.
(erc-fill-wrap-mode, erc-fill-wrap-enable, erc-fill-wrap-disable):
Don't hook on the soon-to-be-removed function interface
`erc-stamp--insert-date-function' because date stamps are now separate
messages.
(erc-fill--wrap-continued-message-p): Restore accidentally discarded
doc string.  Derive context about current message from text props at
`point-min', and use updated property names and utility functions.
Abort when previous message is now hidden.
(erc-fill--wrap-stamp-insert-prefixed-date): Remove unused function,
originally meant to be new in ERC 5.6, and move logic for date-stamp
measuring portion directly to `erc-fill-wrap' itself.
(erc-fill--wrap-measure): New helper function.
(erc-fill-wrap): Use helper `erc-fill--wrap-measure' and incorporate
date-stamp detection and width measuring from removed helper.  Don't
dedent first word for messages of unknown origin, such as those
inserted by `erc-display-line' alone without prior preparation from
`erc-display-message'.
* lisp/erc/erc-goodies.el (erc-readonly-mode, erc-readonly-enable):
Set hook depth explicitly to 70.
* lisp/erc/erc-stamp.el (erc-timestamp-format-left): Mention that a
trailing newline is implicit if not provided and that users who don't
want date stamps should use `erc-timestamp-format-right' instead.
(erc-stamp-mode, erc-stamp-enable): Call `erc-stamp--setup' instead
of `erc-munge-invisibility-spec', and bump hook depth for
`erc-add-timestamp' to 70.
(erc-stamp--current-time): Use `erc-ts' instead of `erc-timestamp'
text property in doc string.
(erc-stamp--skip): New internal variable.
(erc-stamp--allow-unmanaged): New variable for legacy code to force
`erc-add-timestamps' to run when `erc--msg-props' is nil.
(erc-add-timestamp): Always run when `erc-stamp--allow-unmanaged' is
non-nil unless `erc-stamp--skip' is as well because the latter takes
precedence.  Don't add `erc-ts' text prop directly unless
`erc-stamp--allow-unmanaged is non-nil.  Instead, use the new
`erc--msg-props' facility to defer until after modification hooks.
Likewise, don't add `cursor-senor-functions' directly either unless
the same compatibility flag is enabled.  Instead, expect the latter to
be handled by a post-modify hook conditioned on the option
`erc-echo-timestamps'.
(erc-timestamp-last-inserted-left): Mention that the final trailing
newline specified in the format string no longer appears in the
recorded value.
(erc-stamp-prefix-log-filter): Use updated name for timestamp
property as well as helper utility for accessing it.
(erc-stamp--inherited-props): Add doc string.
(erc-insert-timestamp-right): Fix bug involving object cycle where
the time-stamp string would appear in its own `display' property.
(erc-stamp--insert-date-function, erc-stamp--insert-date-hook): Remove
unused internal function-valued interface variable and replace with
the latter, a normal hook.
(erc-stamp--date-format-end, erc-stamp--propertize-left-date-stamp):
New function and auxiliary variable to apply date stamp properties at
the post-modify stage.  Add text property `erc-stamp-type' to inserted
date stamps to help folks distinguish between them and other
left-sided stamps.
(erc-stamp--current-datestamp-left,
erc-stamp--format-date-stamp,
erc-stamp--insert-date-stamp-as-phony-message,
erc-stamp--lr-date-on-pre-modify): New functions and state variable to
help ERC treat date stamps as separate messages while working within
the established mechanism for processing inserted messages.  Shadow
`erc-stamp--invisible-property' when calling `erc-format-timestamp' in
order to prevent date stamps from inheriting other `invisible' props.
These date stamps are special in that they have no business being
hidden along with the current message.
(erc-insert-timestamp-left-and-right): On initial run in any buffer,
remember whether the date stamp needed newline massaging on insertion.
Move all business for inserting date stamps to post-modify hooks, but
run them forcibly if this is the very first date stamp in the current
buffer.  Also mention some specifics related to relevant text props in
the doc string.
(erc-format-timestamp): Don't add `invisible' prop to stamp unless
`erc-stamp--invisible-property' is non-nil.
(erc-stamp--csf-props-updated-p): New local variable.
(erc-munge-invisibility-spec): Restore `cursor-sensor-functions' text
property for existing messages when a user enables the option
mid-session.  Add and remove hooks for use with automatic timestamp
echoing.
(erc-stamp--add-csf-on-post-modify): New function to add
`cursor-sensor-functions' property on post-modify hooks.
(erc-stamp--setup): Perform some additional teardown.
(erc-stamp--on-clear-message): Look for text property `erc-ts' instead
of `erc-timestamp'.
(erc-echo-timestamp, erc--echo-ts-csf): Use utility to find time-stamp
text prop in current message.
(erc-stamp--update-saved-position, erc-stamp--reset-on-clear): Use
hook `erc-stamp--insert-date-hook' instead of excised function-valued
variable interface `erc-stamp--insert-date-function'.
* lisp/erc/erc-truncate.el (erc-truncate-buffer-to-size): Use internal
utility to find beginning of message.
* lisp/erc/erc.el (erc--msg-props, erc--msg-props-overrides): New
internal variables for initializing and conveying metadata-oriented
text properties among insert and send hooks.
(erc-insert-modify-hook): Mention reserved depth ranges for built-in
members in doc string.
(erc-send-action):  Use convenience variable to modifying text props
instead of awkwardly overriding `erc-insert-pre-hook'.
(erc--check-msg-prop, erc--get-inserted-msg-bounds,
erc--get-inserted-msg-prop, erc--with-inserted-msg,
erc--traverse-inserted): New utility functions and macros to help
modules find metadata and message-delimiting text props.
(erc-display-line-1): Ensure the first character of every message in
an ERC buffer has the `erc-msg' property, as well as any other props
in `erc--msg-props', when populated.
(erc--hide-message): Don't bother offsetting start of first message in
a buffer.
(erc--ranked-properties, erc--order-text-properties-from-hash): New
variable and function to convert `erc--msg-props' into a plist
suitable for `add-text-properties'.
(erc-display-message): Make doc string more informative.  Bind and
initialize `erc--msg-props' for use by all hooks.  Respect
`erc--msg-prop-overrides' when non-nil.  Don't add `erc-command'
property.  Instead, ensure `erc--msg-props' contains an `erc-cmd' item
when the parameter PARSED is non-nil.
(erc--own-property-names): Add `erc-stamp-type'.
(erc--get-speaker-bounds): Use helper to find message start.
(erc-process-ctcp-query, erc-send-current-line): Use convenience
variable to leverage framework for manipulating message metadata
instead of overriding `erc-insert-pre-hook'.
(erc-display-msg): Bind `erc--msg-props' for use by all send-related
hooks.  Add text props from table after `erc-send-post-hook'.
(erc-restore-text-properties): Improve doc string.
(erc--get-eq-comparable-cmd): Use `if-let' instead of `if-let*'.
* test/lisp/erc/erc-fill-tests.el (erc-fill-tests--insert-privmsg):
Make phony message more realistic.
(erc-fill-tests--wrap-populate): Shorten overlong line.
(erc-fill-tests--wrap-check-prefixes): Make test utility more vigilant
in asserting no gaps exist in `line-prefix' property interval.
(erc-fill-tests--compare): Compare text props on text-prop values that
are themselves strings.
* test/lisp/erc/erc-scenarios-log.el (erc-scenarios-log--clear-stamp):
Ensure `erc-stamp' is loaded.
* test/lisp/erc/erc-scenarios-match.el
(erc-scenarios-match--stamp-left-current-nick,
erc-scenarios-match--invisible-stamp): Use `default-value' for
`erc-insert-modify-hook' in ordering assertion.
(erc-scenarios-match--find-bol, erc-scenarios-match--find-eol): Remove
unused assertion helper functions.
(erc-scenarios-match--stamp-right-fools-invisible): Remove misplaced
ERT tag from function and use utility to find message bounds.
(erc-scenarios-match--stamp-right-fools-invisible): Use real utility
from main library to find message end.
(erc-scenarios-match--fill-wrap-stamp-dedented-p): New assertion
utility function.
(erc-scenarios-match--hide-fools/stamp-both/fill-wrap) New test.
(erc-scenarios-match--hide-fools/stamp-both/fill-wrap/speak): New
test.
(erc-scenarios-match--stamp-both-invisible-fill-static): Expect
`erc-cmd' at beginning of inserted message's filled line, even if the
line starts with white space.  Also, add new function parameter
`assert-ds', a callback to run when visiting the second date stamp,
which is followed by a hidden message.  In the test of the same name,
expect the date stamp's invisibility interval to begin at the newline
after the previous message and to not contain any existing
invisibility props, namely, those belonging to the subsequent hidden
"fools" message.  Also use shortened "metadata" text prop names.
(erc-scenarios-match--stamp-both-invisible-fill-static--nooffset):
Expect the date stamp's invisibility interval to match its field's
instead of starting and ending sooner.
* test/lisp/erc/erc-stamp-tests.el: Put well-known metadata prop at
the start of the message.
* test/lisp/erc/erc-tests.el (erc--refresh-prompt): Prevent modules
from mutating hooks.
(erc--order-text-properties-from-hash, erc--check-msg-prop): New
tests.
* test/lisp/erc/resources/fill/snapshots/merge-01-start.eld: Update
test data.
* test/lisp/erc/resources/fill/snapshots/merge-02-right.eld: Update
test data.
* test/lisp/erc/resources/fill/snapshots/merge-wrap-01.eld: Update.
* test/lisp/erc/resources/fill/snapshots/monospace-01-start.eld:
Update.
* test/lisp/erc/resources/fill/snapshots/monospace-02-right.eld:
Update.
* test/lisp/erc/resources/fill/snapshots/monospace-03-left.eld:
Update.
* test/lisp/erc/resources/fill/snapshots/monospace-04-reset.eld:
Update.
* test/lisp/erc/resources/fill/snapshots/spacing-01-mono.eld: Update.
* test/lisp/erc/resources/fill/snapshots/stamps-left-01.eld: Update.
* test/lisp/erc/resources/match/fools/fill-wrap.eld: New file.
(Bug#60936)
This commit is contained in:
F. Jason Park 2023-09-21 23:54:31 -07:00
parent a4bae965e0
commit c68dc7786f
21 changed files with 778 additions and 230 deletions

View file

@ -149,7 +149,7 @@ minor-mode maps, and new third-party modules should do the same.
** Option 'erc-timestamp-format-right' deprecated.
Having to account for this option prevented other ERC modules from
easily determining what right-hand stamps would look like before
easily determining what right-sided stamps would look like before
insertion, which is knowledge needed for certain UI decisions. The
way ERC has chosen to address this is imperfect and boils down to
asking users who've customized this option to switch to
@ -290,11 +290,13 @@ continue to modify non-ERC hooks locally whenever possible, especially
in new code.
*** ERC now manages timestamp-related properties a bit differently.
For starters, the 'cursor-sensor-functions' property no longer
For starters, the 'cursor-sensor-functions' text property is absent by
default unless the option 'erc-echo-timestamps' is already enabled on
module init. And when present, the property's value no longer
contains unique closures and thus no longer proves effective for
traversing messages. To compensate, a new property, 'erc-timestamp',
now spans message bodies but not the newlines delimiting them. Also
affecting the 'stamp' module is the deprecation of the function
traversing inserted messages. For now, ERC only provides an internal
means of visiting messages, but a public interface is forthcoming.
Also affecting the 'stamp' module is the deprecation of the function
'erc-insert-aligned' and its removal from client code. Additionally,
the module now merges its 'invisible' property with existing ones and
includes all white space around stamps when doing so.
@ -309,6 +311,23 @@ folded onto the next line. Such inconsistency made stamp detection
overly complex and produced uneven results when toggling stamp
visibility.
*** Date stamps are independent messages.
ERC now inserts "date stamps" generated from the option
'erc-timestamp-format-left' as separate, standalone messages. (This
only matters if 'erc-insert-timestamp-function' is set to its default
value of 'erc-insert-timestamp-left-and-right'.) ERC's near-term UI
goals require exposing these stamps to existing code designed to
operate on complete messages. For example, users likely expect date
stamps to be togglable with 'erc-toggle-timestamps' while also being
immune to hiding from commands like 'erc-match-toggle-hidden-fools'.
Before this change, meeting such expectations demanded brittle
heuristics that checked for the presence of these stamps in the
leading portion of message bodies as well as special casing to act on
these areas without inflicting collateral damage. It may also be
worth noting that as consequence of these changes, the internally
managed variable 'erc-timestamp-last-inserted-left' no longer records
the final trailing newline in 'erc-timestamp-format-left'.
*** The role of a module's Custom group is now more clearly defined.
Associating built-in modules with Custom groups and provided library
features has improved. More specifically, a module's group now enjoys

View file

@ -158,6 +158,11 @@ You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
(when (or erc-fill--function erc-fill-function)
;; skip initial empty lines
(goto-char (point-min))
;; Note the following search pattern was altered in 5.6 to adapt
;; to a change in Emacs regexp behavior that turned out to be a
;; regression (which has since been fixed). The patterns appear
;; to be equivalent in practice, so this was left as is (wasn't
;; reverted) to avoid additional git-blame(1)-related churn.
(while (and (looking-at (rx bol (* (in " \t")) eol))
(zerop (forward-line 1))))
(unless (eobp)
@ -167,12 +172,10 @@ You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
(when-let* ((erc-fill-line-spacing)
(p (point-min)))
(widen)
(when (or (and-let* ((cmd (get-text-property p 'erc-command)))
(memq cmd erc-fill--spaced-commands))
(when (or (erc--check-msg-prop 'erc-cmd erc-fill--spaced-commands)
(and-let* ((cmd (save-excursion
(forward-line -1)
(get-text-property (point)
'erc-command))))
(get-text-property (point) 'erc-cmd))))
(memq cmd erc-fill--spaced-commands)))
(put-text-property (1- p) p
'line-spacing erc-fill-line-spacing))))))))
@ -181,15 +184,17 @@ You can put this on `erc-insert-modify-hook' and/or `erc-send-modify-hook'."
"Fills a text such that messages start at column `erc-fill-static-center'."
(save-restriction
(goto-char (point-min))
(looking-at "^\\(\\S-+\\)")
(let ((nick (match-string 1)))
(when-let (((looking-at "^\\(\\S-+\\)"))
((not (erc--check-msg-prop 'erc-msg 'datestamp)))
(nick (match-string 1)))
(progn
(let ((fill-column (- erc-fill-column (erc-timestamp-offset)))
(fill-prefix (make-string erc-fill-static-center 32)))
(insert (make-string (max 0 (- erc-fill-static-center
(length nick) 1))
32))
(erc-fill-regarding-timestamp))
(erc-restore-text-properties))))
(erc-restore-text-properties)))))
(defun erc-fill-variable ()
"Fill from `point-min' to `point-max'."
@ -423,8 +428,6 @@ is not recommended."
(eq (default-value 'erc-insert-timestamp-function)
#'erc-insert-timestamp-left)))
(setq erc-fill--function #'erc-fill-wrap)
(add-function :after (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date)
(when erc-fill-wrap-merge
(add-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p nil t))
@ -436,9 +439,7 @@ is not recommended."
(kill-local-variable 'erc-fill--function)
(kill-local-variable 'erc-fill--wrap-visual-keys)
(remove-hook 'erc-button--prev-next-predicate-functions
#'erc-fill--wrap-merged-button-p t)
(remove-function (local 'erc-stamp--insert-date-function)
#'erc-fill--wrap-stamp-insert-prefixed-date))
#'erc-fill--wrap-merged-button-p t))
'local)
(defvar-local erc-fill--wrap-length-function nil
@ -456,6 +457,9 @@ parties.")
(defvar-local erc-fill--wrap-max-lull (* 24 60 60))
(defun erc-fill--wrap-continued-message-p ()
"Return non-nil when the current speaker hasn't changed.
That is, indicate whether the text just inserted is from the same
sender as that of the previous \"PRIVMSG\"."
(prog1 (and-let*
((m (or erc-fill--wrap-last-msg
(setq erc-fill--wrap-last-msg (point-min-marker))
@ -463,45 +467,37 @@ parties.")
((< (1+ (point-min)) (- (point) 2)))
(props (save-restriction
(widen)
(when (eq 'erc-timestamp (field-at-pos m))
(set-marker m (field-end m)))
(and-let*
(((eq 'PRIVMSG (get-text-property m 'erc-command)))
((not (eq (get-text-property m 'erc-ctcp)
'ACTION)))
(((eq 'PRIVMSG (get-text-property m 'erc-cmd)))
((not (eq (get-text-property m 'erc-msg) 'ACTION)))
((not (invisible-p m)))
(spr (next-single-property-change m 'erc-speaker)))
(cons (get-text-property m 'erc-timestamp)
(cons (get-text-property m 'erc-ts)
(get-text-property spr 'erc-speaker)))))
(ts (pop props))
(props)
((not (time-less-p (erc-stamp--current-time) ts)))
((time-less-p (time-subtract (erc-stamp--current-time) ts)
erc-fill--wrap-max-lull))
;; Assume presence of leading angle bracket or hyphen.
(speaker (next-single-property-change (point-min) 'erc-speaker))
((not (eq (get-text-property speaker 'erc-ctcp) 'ACTION)))
((not (erc--check-msg-prop 'erc-ctcp 'ACTION)))
(nick (get-text-property speaker 'erc-speaker))
((erc-nick-equal-p props nick))))
(set-marker erc-fill--wrap-last-msg (point-min))))
(defun erc-fill--wrap-stamp-insert-prefixed-date (&rest args)
"Apply `line-prefix' property to args."
(let* ((ts-left (car args))
(start)
;; Insert " " to simulate gap between <speaker> and msg beg.
(end (save-excursion (skip-chars-backward "\n")
(setq start (pos-bol))
(insert " ")
(point)))
(width (if (and erc-fill-wrap-use-pixels
(fboundp 'buffer-text-pixel-size))
(save-restriction (narrow-to-region start end)
(list (car (buffer-text-pixel-size))))
(length (string-trim-left ts-left)))))
(delete-region (1- end) end)
;; Use `point-min' instead of `start' to cover leading newilnes.
(put-text-property (point-min) (point) 'line-prefix
`(space :width (- erc-fill--wrap-value ,width))))
args)
(defun erc-fill--wrap-measure (beg end)
"Return display spec width for inserted region between BEG and END.
Ignore any `invisible' props that may be present when figuring."
(if (and erc-fill-wrap-use-pixels (fboundp 'buffer-text-pixel-size))
;; `buffer-text-pixel-size' can move point!
(save-excursion
(save-restriction
(narrow-to-region beg end)
(let* ((buffer-invisibility-spec)
(rv (car (buffer-text-pixel-size))))
(if (zerop rv) 0 (list rv)))))
(- end beg)))
;; An escape hatch for third-party code expecting speakers of ACTION
;; messages to be exempt from `line-prefix'. This could be converted
@ -518,33 +514,38 @@ See `erc-fill-wrap-mode' for details."
(goto-char (point-min))
(let ((len (or (and erc-fill--wrap-length-function
(funcall erc-fill--wrap-length-function))
(progn
(and-let* ((msg-prop (erc--check-msg-prop 'erc-msg)))
(when-let ((e (erc--get-speaker-bounds))
(b (pop e))
((or erc-fill--wrap-action-dedent-p
(not (eq (get-text-property b 'erc-ctcp)
(not (erc--check-msg-prop 'erc-ctcp
'ACTION)))))
(goto-char e))
(skip-syntax-forward "^-")
(forward-char)
;; Using the `invisible' property might make more
;; sense, but that would require coordination
;; with other modules, like `erc-match'.
(cond ((and erc-fill-wrap-merge
(cond ((eq msg-prop 'datestamp)
(when erc-fill--wrap-last-msg
(set-marker erc-fill--wrap-last-msg (point-min)))
(save-excursion
(goto-char (point-max))
(skip-chars-backward "\n")
(let ((beg (pos-bol)))
(insert " ")
(prog1 (erc-fill--wrap-measure beg (point))
(delete-region (1- (point)) (point))))))
((and erc-fill-wrap-merge
(erc-fill--wrap-continued-message-p))
(put-text-property (point-min) (point)
'display "")
0)
((and erc-fill-wrap-use-pixels
(fboundp 'buffer-text-pixel-size))
(save-restriction
(narrow-to-region (point-min) (point))
(list (car (buffer-text-pixel-size)))))
(t (- (point) (point-min))))))))
(erc-put-text-properties (point-min) (1- (point-max)) ; exclude "\n"
'(line-prefix wrap-prefix) nil
`((space :width (- erc-fill--wrap-value ,len))
(space :width erc-fill--wrap-value))))))
(t
(erc-fill--wrap-measure (point-min) (point))))))))
(add-text-properties
(point-min) (1- (point-max)) ; exclude "\n"
`( line-prefix (space :width ,(if len
`(- erc-fill--wrap-value ,len)
'erc-fill--wrap-value))
wrap-prefix (space :width erc-fill--wrap-value))))))
;; FIXME use own text property to avoid false positives.
(defun erc-fill--wrap-merged-button-p (point)

View file

@ -242,8 +242,8 @@ variable `erc-input-line-position'."
;;;###autoload(autoload 'erc-readonly-mode "erc-goodies" nil t)
(define-erc-module readonly nil
"This mode causes all inserted text to be read-only."
((add-hook 'erc-insert-post-hook #'erc-make-read-only)
(add-hook 'erc-send-post-hook #'erc-make-read-only))
((add-hook 'erc-insert-post-hook #'erc-make-read-only 70)
(add-hook 'erc-send-post-hook #'erc-make-read-only 70))
((remove-hook 'erc-insert-post-hook #'erc-make-read-only)
(remove-hook 'erc-send-post-hook #'erc-make-read-only)))

View file

@ -55,21 +55,22 @@ If nil, timestamping is turned off."
:type '(choice (const nil)
(string)))
;; FIXME remove surrounding whitespace from default value and have
;; `erc-insert-timestamp-left-and-right' add it before insertion.
(defcustom erc-timestamp-format-left "\n[%a %b %e %Y]\n"
"If set to a string, messages will be timestamped.
This string is processed using `format-time-string'.
Good examples are \"%T\" and \"%H:%M\".
This timestamp is used for timestamps on the left side of the
screen when `erc-insert-timestamp-function' is set to
`erc-insert-timestamp-left-and-right'.
If nil, timestamping is turned off."
:type '(choice (const nil)
(string)))
"Format recognized by `format-time-string' for date stamps.
Only considered when `erc-insert-timestamp-function' is set to
`erc-insert-timestamp-left-and-right'. Used for displaying date
stamps on their own line, between messages. ERC inserts this
flavor of stamp as a separate \"psuedo message\", so a final
newline isn't necessary. For compatibility, only additional
trailing newlines beyond the first become empty lines. For
example, the default value results in an empty line after the
previous message, followed by the timestamp on its own line,
followed immediately by the next message on the next line. ERC
expects to display these stamps less frequently, so the
formatting specifiers should reflect that. To omit these stamps
entirely, use a different `erc-insert-timestamp-function', such
as `erc-timestamp-format-right'."
:type 'string)
(defcustom erc-timestamp-format-right nil
"If set to a string, messages will be timestamped.
@ -175,9 +176,9 @@ from entering them and instead jump over them."
;;;###autoload(autoload 'erc-timestamp-mode "erc-stamp" nil t)
(define-erc-module stamp timestamp
"This mode timestamps messages in the channel buffers."
((add-hook 'erc-mode-hook #'erc-munge-invisibility-spec)
(add-hook 'erc-insert-modify-hook #'erc-add-timestamp 60)
(add-hook 'erc-send-modify-hook #'erc-add-timestamp 60)
((add-hook 'erc-mode-hook #'erc-stamp--setup)
(add-hook 'erc-insert-modify-hook #'erc-add-timestamp 70)
(add-hook 'erc-send-modify-hook #'erc-add-timestamp 70)
(add-hook 'erc-mode-hook #'erc-stamp--recover-on-reconnect)
(add-hook 'erc--pre-clear-functions #'erc-stamp--reset-on-clear)
(unless erc--updating-modules-p (erc-buffer-do #'erc-stamp--setup)))
@ -214,18 +215,27 @@ the stamp passed to `erc-insert-timestamp-function'.")
(cl-defgeneric erc-stamp--current-time ()
"Return a lisp time object to associate with an IRC message.
This becomes the message's `erc-timestamp' text property."
This becomes the message's `erc-ts' text property."
(erc-compat--current-lisp-time))
(cl-defmethod erc-stamp--current-time :around ()
(or erc-stamp--current-time (cl-call-next-method)))
(defvar erc-stamp--skip nil
"Non-nil means inhibit `erc-add-timestamp' completely.")
(defvar erc-stamp--allow-unmanaged nil
"Non-nil means `erc-add-timestamp' runs unconditionally.
Escape hatch for third-parties using lower-level API functions,
such as `erc-display-line', directly.")
(defun erc-add-timestamp ()
"Add timestamp and text-properties to message.
This function is meant to be called from `erc-insert-modify-hook'
or `erc-send-modify-hook'."
(progn ; remove this `progn' on next major refactor
(unless (or erc-stamp--skip (and (not erc-stamp--allow-unmanaged)
(null erc--msg-props)))
(let* ((ct (erc-stamp--current-time))
(invisible (get-text-property (point-min) 'invisible))
(erc-stamp--invisible-property
@ -233,6 +243,8 @@ or `erc-send-modify-hook'."
(if invisible `(timestamp ,@(ensure-list invisible)) 'timestamp))
(skipp (and erc-stamp--skip-when-invisible invisible))
(erc-stamp--current-time ct))
(when erc--msg-props
(puthash 'erc-ts ct erc--msg-props))
(unless skipp
(funcall erc-insert-timestamp-function
(erc-format-timestamp ct erc-timestamp-format)))
@ -244,12 +256,13 @@ or `erc-send-modify-hook'."
(erc-away-time))
(funcall erc-insert-away-timestamp-function
(erc-format-timestamp ct erc-away-timestamp-format)))
(when erc-stamp--allow-unmanaged
(add-text-properties (point-min) (1- (point-max))
;; It's important for the function to
;; be different on different entries (bug#22700).
(list 'cursor-sensor-functions
;; Regions are no longer contiguous ^
'(erc--echo-ts-csf) 'erc-timestamp ct)))))
'(erc--echo-ts-csf) 'erc-ts ct))))))
(defvar-local erc-timestamp-last-window-width nil
"The width of the last window that showed the current buffer.
@ -260,9 +273,11 @@ buffer is not shown in any window.")
"Last timestamp inserted into the buffer.")
(defvar-local erc-timestamp-last-inserted-left nil
"Last timestamp inserted into the left side of the buffer.
This is used when `erc-insert-timestamp-function' is set to
`erc-timestamp-left-and-right'")
"Last \"date stamp\" inserted into the left side of the buffer.
Used when `erc-insert-timestamp-function' is set to
`erc-timestamp-left-and-right'. If the format string specified
by `erc-timestamp-format-left' includes trailing newlines, this
value omits the last one.")
(defvar-local erc-timestamp-last-inserted-right nil
"Last timestamp inserted into the right side of the buffer.
@ -362,19 +377,27 @@ non-nil."
(goto-char (point-min))
(while
(progn
(when-let* (((< (point) (pos-eol)))
(when-let (((< (point) (pos-eol)))
(end (1- (pos-eol)))
((eq 'erc-timestamp (field-at-pos end)))
(beg (field-beginning end))
;; Skip a line that's just a timestamp.
((> beg (point))))
(delete-region beg (1+ end)))
(when-let (time (get-text-property (point) 'erc-timestamp))
(when-let (time (erc--get-inserted-msg-prop 'erc-ts))
(insert (format-time-string "[%H:%M:%S] " time)))
(zerop (forward-line))))
"")
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix))
;; These are currently extended manually, but we could also bind
;; `text-property-default-nonsticky' and call `insert-and-inherit'
;; instead of `insert', but we'd have to pair the props with differing
;; boolean values for left and right stamps. Also, since this hook
;; runs last, we can't expect overriding sticky props to be absent,
;; even though, as of 5.6, `front-sticky' is only added by the
;; `readonly' module after hooks run.
(defvar erc-stamp--inherited-props '(line-prefix wrap-prefix)
"Extant properties at the start of a message inherited by the stamp.")
(declare-function erc--remove-text-properties "erc" (string))
@ -573,8 +596,11 @@ printed just after each line's text (no alignment)."
;; intervening white space unless a hard break is warranted.
(pcase erc-timestamp-use-align-to
((guard erc-stamp--display-margin-mode)
(put-text-property 0 (length string)
'display `((margin right-margin) ,string) string))
(let ((s (propertize (substring-no-properties string)
'invisible erc-stamp--invisible-property)))
(put-text-property 0 (length string) 'display
`((margin right-margin) ,s)
string)))
((and 't (guard (< col pos)))
(insert " ")
(put-text-property from (point) 'display `(space :align-to ,pos)))
@ -599,30 +625,94 @@ printed just after each line's text (no alignment)."
(when erc-timestamp-intangible
(erc-put-text-property from (1+ (point)) 'cursor-intangible t)))))
(defvar erc-stamp--insert-date-function #'insert
"Function to insert left \"left-right date\" stamp.
A local module might use this to modify text properties,
`insert-before-markers' or renarrow the region after insertion.")
(defvar erc-stamp--insert-date-hook nil
"Functions appended to send and modify hooks when inserting date stamp.")
(defvar-local erc-stamp--date-format-end nil
"Substring index marking usable portion of date stamp format.")
(defun erc-stamp--propertize-left-date-stamp ()
(add-text-properties (point-min) (1- (point-max))
'(field erc-timestamp erc-stamp-type date-left))
(erc--hide-message 'timestamp))
;; A kludge to pass state from insert hook to nested insert hook.
(defvar erc-stamp--current-datestamp-left nil)
(defun erc-stamp--format-date-stamp (ct)
"Format left date stamp with `erc-timestamp-format-left'."
(unless erc-stamp--date-format-end
;; Don't add text properties to the trailing newline.
(setq erc-stamp--date-format-end
(if (string-suffix-p "\n" erc-timestamp-format-left) -1 0)))
;; Ignore existing `invisible' prop value because date stamps should
;; never be hideable except via `timestamp'.
(let (erc-stamp--invisible-property)
(erc-format-timestamp ct (substring erc-timestamp-format-left
0 erc-stamp--date-format-end))))
;; Calling `erc-display-message' from within a hook it's currently
;; running is roundabout, but it's a definite means of ensuring hooks
;; can act on the date stamp as a standalone message to do things like
;; adjust invisibility props.
(defun erc-stamp--insert-date-stamp-as-phony-message (string)
(cl-assert (string-empty-p string))
(setq string erc-stamp--current-datestamp-left)
(cl-assert string)
(let ((erc-stamp--skip t)
(erc--msg-props (map-into `((erc-msg . datestamp)
(erc-ts . ,erc-stamp--current-time))
'hash-table))
(erc-send-modify-hook `(,@erc-send-modify-hook
erc-stamp--propertize-left-date-stamp
,@erc-stamp--insert-date-hook))
(erc-insert-modify-hook `(,@erc-insert-modify-hook
erc-stamp--propertize-left-date-stamp
,@erc-stamp--insert-date-hook)))
(erc-display-message nil nil (current-buffer) string)
(setq erc-timestamp-last-inserted-left string)))
(defun erc-stamp--lr-date-on-pre-modify (_)
(when-let ((ct (or erc-stamp--current-time (erc-stamp--current-time)))
(rendered (erc-stamp--format-date-stamp ct))
((not (string-equal rendered erc-timestamp-last-inserted-left)))
(erc-stamp--current-datestamp-left rendered)
(erc-insert-timestamp-function
#'erc-stamp--insert-date-stamp-as-phony-message))
(save-restriction
(narrow-to-region (or erc--insert-marker erc-insert-marker)
(or erc--insert-marker erc-insert-marker))
(let (erc-timestamp-format erc-away-timestamp-format)
(erc-add-timestamp)))))
(defun erc-insert-timestamp-left-and-right (string)
"Insert a stamp on either side when it changes.
When the deprecated option `erc-timestamp-format-right' is nil,
use STRING, which originates from `erc-timestamp-format', for the
right-hand stamp. Use `erc-timestamp-format-left' for the
left-hand stamp and expect it to change less frequently."
right-hand stamp. Use `erc-timestamp-format-left' for formatting
the left-sided \"date stamp,\" and expect it to change less
frequently. Include all but the final trailing newline present
in the latter (if any) as part of the `erc-timestamp' field.
Allow the stamp's `invisible' property to span that same interval
but also cover the previous newline, in order to satisfy folding
requirements related to `erc-legacy-invisible-bounds-p'.
Additionally, ensure every date stamp is identifiable as such so
that internal modules can easily distinguish between other
left-sided stamps and date stamps inserted by this function."
(unless erc-stamp--date-format-end
(add-hook 'erc-insert-pre-hook #'erc-stamp--lr-date-on-pre-modify -95 t)
(add-hook 'erc-send-pre-functions #'erc-stamp--lr-date-on-pre-modify -95 t)
(let ((erc--insert-marker (point-min-marker)))
(set-marker-insertion-type erc--insert-marker t)
(erc-stamp--lr-date-on-pre-modify nil)
(narrow-to-region erc--insert-marker (point-max))
(set-marker erc--insert-marker nil)))
(let* ((ct (or erc-stamp--current-time (erc-stamp--current-time)))
(ts-left (erc-format-timestamp ct erc-timestamp-format-left))
(ts-right (with-suppressed-warnings
((obsolete erc-timestamp-format-right))
(if erc-timestamp-format-right
(erc-format-timestamp ct erc-timestamp-format-right)
string))))
;; insert left timestamp
(unless (string-equal ts-left erc-timestamp-last-inserted-left)
(goto-char (point-min))
(erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left)
(funcall erc-stamp--insert-date-function ts-left)
(setq erc-timestamp-last-inserted-left ts-left))
;; insert right timestamp
(let ((erc-timestamp-only-if-changed-flag t)
(erc-timestamp-last-inserted erc-timestamp-last-inserted-right))
@ -639,8 +729,9 @@ Return the empty string if FORMAT is nil."
(let ((ts (format-time-string format time erc-stamp--tz)))
(erc-put-text-property 0 (length ts)
'font-lock-face 'erc-timestamp-face ts)
(when erc-stamp--invisible-property
(erc-put-text-property 0 (length ts) 'invisible
erc-stamp--invisible-property ts)
erc-stamp--invisible-property ts))
;; N.B. Later use categories instead of this harmless, but
;; inelegant, hack. -- BPT
(and erc-timestamp-intangible
@ -649,6 +740,8 @@ Return the empty string if FORMAT is nil."
ts)
""))
(defvar-local erc-stamp--csf-props-updated-p nil)
;; This function is used to munge `buffer-invisibility-spec' to an
;; appropriate value. Currently, it only handles timestamps, thus its
;; location. If you add other features which affect invisibility,
@ -661,10 +754,23 @@ Return the empty string if FORMAT is nil."
(cursor-intangible-mode -1)))
(if erc-echo-timestamps
(progn
(dolist (hook '(erc-insert-post-hook erc-send-post-hook))
(add-hook hook #'erc-stamp--add-csf-on-post-modify nil t))
(erc--restore-initialize-priors erc-stamp-mode
erc-stamp--csf-props-updated-p nil)
(unless (or erc-stamp--allow-unmanaged erc-stamp--csf-props-updated-p)
(setq erc-stamp--csf-props-updated-p t)
(let ((erc--msg-props (map-into '((erc-ts . t)) 'hash-table)))
(with-silent-modifications
(erc--traverse-inserted (point-min) erc-insert-marker
#'erc-stamp--add-csf-on-post-modify))))
(cursor-sensor-mode +1) ; idempotent
(when (>= emacs-major-version 29)
(add-function :before-until (local 'clear-message-function)
#'erc-stamp--on-clear-message)))
(dolist (hook '(erc-insert-post-hook erc-send-post-hook))
(remove-hook hook #'erc-stamp--add-csf-on-post-modify t))
(kill-local-variable 'erc-stamp--csf-props-updated-p)
(when (bound-and-true-p cursor-sensor-mode)
(cursor-sensor-mode -1))
(remove-function (local 'clear-message-function)
@ -673,12 +779,22 @@ Return the empty string if FORMAT is nil."
(add-to-invisibility-spec 'timestamp)
(remove-from-invisibility-spec 'timestamp)))
(defun erc-stamp--add-csf-on-post-modify ()
"Add `cursor-sensor-functions' to narrowed buffer."
(when (erc--check-msg-prop 'erc-ts)
(put-text-property (point-min) (1- (point-max))
'cursor-sensor-functions '(erc--echo-ts-csf))))
(defun erc-stamp--setup ()
"Enable or disable buffer-local `erc-stamp-mode' modifications."
(if erc-stamp-mode
(erc-munge-invisibility-spec)
(let (erc-echo-timestamps erc-hide-timestamps erc-timestamp-intangible)
(erc-munge-invisibility-spec))))
(erc-munge-invisibility-spec))
;; Undo local mods from `erc-insert-timestamp-left-and-right'.
(remove-hook 'erc-insert-pre-hook #'erc-stamp--lr-date-on-pre-modify t)
(remove-hook 'erc-send-pre-functions #'erc-stamp--lr-date-on-pre-modify t)
(kill-local-variable 'erc-stamp--date-format-end)))
(defun erc-hide-timestamps ()
"Hide timestamp information from display."
@ -714,7 +830,7 @@ enabled when the message was inserted."
(defun erc-stamp--on-clear-message (&rest _)
"Return `dont-clear-message' when operating inside the same stamp."
(and erc-stamp--last-stamp erc-echo-timestamps
(eq (get-text-property (point) 'erc-timestamp) erc-stamp--last-stamp)
(eq (erc--get-inserted-msg-prop 'erc-ts) erc-stamp--last-stamp)
'dont-clear-message))
(defun erc-echo-timestamp (dir stamp &optional zone)
@ -724,7 +840,7 @@ hours (or seconds, if its abs value is larger than 14), and
interpret a \"raw\" prefix as UTC. To specify a zone for use
with the option `erc-echo-timestamps', see the companion option
`erc-echo-timestamp-zone'."
(interactive (list nil (get-text-property (point) 'erc-timestamp)
(interactive (list nil (erc--get-inserted-msg-prop 'erc-ts)
(pcase current-prefix-arg
((and (pred numberp) v)
(if (<= (abs v) 14) (* v 3600) v))
@ -738,18 +854,18 @@ with the option `erc-echo-timestamps', see the companion option
(setq erc-stamp--last-stamp nil))))
(defun erc--echo-ts-csf (_window _before dir)
(erc-echo-timestamp dir (get-text-property (point) 'erc-timestamp)))
(erc-echo-timestamp dir (erc--get-inserted-msg-prop 'erc-ts)))
(defun erc-stamp--update-saved-position (&rest _)
(remove-function (local 'erc-stamp--insert-date-function)
#'erc-stamp--update-saved-position)
(move-marker erc-last-saved-position (1- (point))))
(remove-hook 'erc-stamp--insert-date-hook
#'erc-stamp--update-saved-position t)
(move-marker erc-last-saved-position (1- (point-max))))
(defun erc-stamp--reset-on-clear (pos)
"Forget last-inserted stamps when POS is at insert marker."
(when (= pos (1- erc-insert-marker))
(add-function :after (local 'erc-stamp--insert-date-function)
#'erc-stamp--update-saved-position)
(add-hook 'erc-stamp--insert-date-hook
#'erc-stamp--update-saved-position 0 t)
(setq erc-timestamp-last-inserted nil
erc-timestamp-last-inserted-left nil
erc-timestamp-last-inserted-right nil)))

View file

@ -102,7 +102,7 @@ present in `erc-modules'."
;; Truncate at message boundary (formerly line boundary
;; before 5.6).
(goto-char end)
(goto-char (or (previous-single-property-change (point) 'erc-command)
(goto-char (or (erc--get-inserted-msg-bounds 'beg)
(pos-bol)))
(setq end (point))
;; try to save the current buffer using

View file

@ -135,9 +135,11 @@ concerning buffers."
"Running scripts at startup and with /LOAD."
:group 'erc)
;; Forward declarations
(defvar erc-message-parsed)
(defvar erc-message-parsed) ; only known to this file
(defvar erc--msg-props nil)
(defvar erc--msg-prop-overrides nil)
;; Forward declarations
(defvar tabbar--local-hlf)
(defvar motif-version-string)
(defvar gtk-version-string)
@ -1139,9 +1141,13 @@ if they wish to avoid sending of a particular string.")
"Insertion hook for functions that will change the text's appearance.
This hook is called just after `erc-insert-pre-hook' when the value
of `erc-insert-this' is t.
While this hook is run, narrowing is in effect and `current-buffer' is
the buffer where the text got inserted. One possible value to add here
is `erc-fill'."
ERC runs this hook with the buffer narrowed to the bounds of the
inserted message plus a trailing newline. Built-in modules place
their hook members at depths between 20 and 80, with those from
the stamp module always running last. Use the functions
`erc-find-parsed-property' and `erc-get-parsed-vector' to locate
and extract the `erc-response' object for the inserted message."
:group 'erc-hooks
:type 'hook)
@ -2871,11 +2877,10 @@ If ARG is non-nil, show the *erc-protocol* buffer."
(defun erc-send-action (tgt str &optional force)
"Send CTCP ACTION information described by STR to TGT."
(erc-send-ctcp-message tgt (format "ACTION %s" str) force)
(let ((erc-insert-pre-hook
(cons (lambda (s) ; Leave newline be.
(put-text-property 0 (1- (length s)) 'erc-command 'PRIVMSG s)
(put-text-property 0 (1- (length s)) 'erc-ctcp 'ACTION s))
erc-insert-pre-hook))
;; Allow hooks that act on inserted PRIVMSG and NOTICES to process us.
(let ((erc--msg-prop-overrides '((erc-msg . msg)
(erc-cmd . PRIVMSG)
(erc-ctcp . ACTION)))
(nick (erc-current-nick)))
(setq nick (propertize nick 'erc-speaker nick))
(erc-display-message nil '(t action input) (current-buffer)
@ -2934,6 +2939,67 @@ debugging purposes, try `erc-debug-irc-protocol'."
(delete-region (point) (1- erc-input-marker))))
(run-hooks 'erc--refresh-prompt-hook)))
(defun erc--check-msg-prop (prop &optional val)
"Return PROP's value in `erc--msg-props' when populated.
If VAL is a list, return non-nil if PROP appears in VAL. If VAL
is otherwise non-nil, return non-nil if VAL compares `eq' to the
stored value. Otherwise, return the stored value."
(and-let* ((erc--msg-props)
(v (gethash prop erc--msg-props)))
(if (consp val) (memq v val) (if val (eq v val) v))))
(defmacro erc--get-inserted-msg-bounds (&optional only point)
"Return the bounds of a message in an ERC buffer.
Return ONLY one side when the first arg is `end' or `beg'. With
POINT, search from POINT instead of `point'."
`(let* ((point ,(or point '(point)))
(at-start-p (get-text-property point 'erc-msg)))
(and-let*
(,@(and (member only '(nil 'beg))
'((b (or (and at-start-p point)
(and-let*
((p (previous-single-property-change point
'erc-msg)))
(if (= p (1- point)) point (1- p)))))))
,@(and (member only '(nil 'end))
'((e (1- (next-single-property-change
(if at-start-p (1+ point) point)
'erc-msg nil erc-insert-marker))))))
,(pcase only
('(quote beg) 'b)
('(quote end) 'e)
(_ '(cons b e))))))
(defun erc--get-inserted-msg-prop (prop)
"Return the value of text property PROP for some message at point."
(and-let* ((stack-pos (erc--get-inserted-msg-bounds 'beg)))
(get-text-property stack-pos prop)))
(defmacro erc--with-inserted-msg (&rest body)
"Simulate narrowing performed for send and insert hooks, and run BODY.
Expect callers to know that this doesn't wrap BODY in
`with-silent-modifications' or bind a temporary `erc--msg-props'."
`(when-let ((bounds (erc--get-inserted-msg-bounds)))
(save-restriction
(narrow-to-region (car bounds) (1+ (cdr bounds)))
,@body)))
(defun erc--traverse-inserted (beg end fn)
"Visit messages between BEG and END and run FN in narrowed buffer."
(setq end (min end (marker-position erc-insert-marker)))
(save-excursion
(goto-char beg)
(let ((b (if (get-text-property (point) 'erc-msg)
(point)
(next-single-property-change (point) 'erc-msg nil end))))
(while-let ((b)
((< b end))
(e (next-single-property-change (1+ b) 'erc-msg nil end)))
(save-restriction
(narrow-to-region b e)
(funcall fn))
(setq b e)))))
(defvar erc--insert-marker nil
"Internal override for `erc-insert-marker'.")
@ -2981,7 +3047,13 @@ If STRING is nil, the function does nothing."
(run-hooks 'erc-insert-post-hook)
(when erc-remove-parsed-property
(remove-text-properties (point-min) (point-max)
'(erc-parsed nil tags nil))))
'(erc-parsed nil tags nil)))
(cl-assert (> (- (point-max) (point-min)) 1))
(let ((props (if erc--msg-props
(erc--order-text-properties-from-hash
erc--msg-props)
'(erc-msg unknown))))
(add-text-properties (point-min) (1+ (point-min)) props)))
(erc--refresh-prompt)))))
(run-hooks 'erc-insert-done-hook)
(erc-update-undo-list (- (or (marker-position (or erc--insert-marker
@ -3112,7 +3184,11 @@ preceding newline to its last non-newline character.")
(defun erc--hide-message (value)
"Apply `invisible' text-property with VALUE to current message.
Expect to run in a narrowed buffer during message insertion."
Expect to run in a narrowed buffer during message insertion.
Begin the invisible interval at the previous message's trailing
newline and end before the current message's. If the preceding
message ends in a double newline or there is no previous message,
don't bother including the preceding newline."
(if erc-legacy-invisible-bounds-p
;; Before ERC 5.6, this also used to add an `intangible'
;; property, but the docs say it's now obsolete.
@ -3121,8 +3197,25 @@ Expect to run in a narrowed buffer during message insertion."
(end (point-max)))
(save-restriction
(widen)
(when (or (<= beg 4) (= ?\n (char-before (- beg 2))))
(cl-incf beg))
(erc--merge-prop (1- beg) (1- end) 'invisible value)))))
(defvar erc--ranked-properties '(erc-msg erc-ts erc-cmd))
(defun erc--order-text-properties-from-hash (table)
"Return a plist of text props from items in TABLE.
Ensure props in `erc--ranked-properties' appear last and in
reverse order so they end up sorted in buffer interval plists for
retrieval by `text-properties-at' and friends."
(let (out)
(dolist (k erc--ranked-properties)
(when-let ((v (gethash k table)))
(remhash k table)
(setq out (nconc (list k v) out))))
(maphash (lambda (k v) (setq out (nconc (list k v) out))) table)
out))
(defun erc-display-message-highlight (type string)
"Highlight STRING according to TYPE, where erc-TYPE-face is an ERC face.
@ -3336,23 +3429,52 @@ returns non-nil."
(defun erc-display-message (parsed type buffer msg &rest args)
"Display MSG in BUFFER.
ARGS, PARSED, and TYPE are used to format MSG sensibly.
Insert MSG or text derived from MSG into an ERC buffer, possibly
after applying formatting by way of either a `format-spec' known
to a message-catalog entry or a TYPE known to a specialized
string handler. Additionally, derive internal metadata, faces,
and other text properties from the various overloaded parameters,
such as PARSED, when it's an `erc-response' object, and MSG, when
it's a key (symbol) for a \"message catalog\" entry. Expect
ARGS, when applicable, to be `format-spec' args known to such an
entry, and TYPE, when non-nil, to be a symbol handled by
`erc-display-message-highlight' (necessarily accompanied by a
string MSG).
When TYPE is a list of symbols, call handlers from left to right
without influencing how they behave when encountering existing
faces. As of ERC 5.6, expect a TYPE of (notice error) to insert
MSG with `font-lock-face' as `erc-error-face' throughout.
However, when the list of symbols begins with t, tell compatible
handlers to compose rather than clobber faces. For example, as
of ERC 5.6, expect a TYPE of (t notice error) to result in MSG's
`font-lock-face' being (erc-error-face erc-notice-face)
throughout when `erc-notice-highlight-type' is set to its default
`all'.
handlers to compose rather than clobber faces. For example,
expect a TYPE of (t notice error) to result in `font-lock-face'
being (erc-error-face erc-notice-face) throughout MSG when
`erc-notice-highlight-type' is left at its default, `all'.
See also `erc-format-message' and `erc-display-line'."
As of ERC 5.6, assume user code will use this function instead of
`erc-display-line' when it's important that insert hooks treat
MSG in a manner befitting messages received from a server. That
is, expect to process most nontrivial informational messages, for
which PARSED is typically nil, when the caller desires
buttonizing and other effects."
(let ((string (if (symbolp msg)
(apply #'erc-format-message msg args)
msg))
(erc--msg-props
(or erc--msg-props
(let* ((table (make-hash-table :size 5))
(cmd (and parsed (erc--get-eq-comparable-cmd
(erc-response.command parsed))))
(m (cond ((and msg (symbolp msg)) msg)
((and cmd (memq cmd '(PRIVMSG NOTICE)) 'msg))
(t 'unknown))))
(puthash 'erc-msg m table)
(when cmd
(puthash 'erc-cmd cmd table))
(and erc--msg-prop-overrides
(pcase-dolist (`(,k . ,v) erc--msg-prop-overrides)
(puthash k v table)))
table)))
(erc-message-parsed parsed))
(setq string
(cond
@ -3371,9 +3493,6 @@ See also `erc-format-message' and `erc-display-line'."
(erc-display-line string buffer)
(unless (erc-hide-current-message-p parsed)
(erc-put-text-property 0 (length string) 'erc-parsed parsed string)
(put-text-property
0 (length string) 'erc-command
(erc--get-eq-comparable-cmd (erc-response.command parsed)) string)
(when (erc-response.tags parsed)
(erc-put-text-property 0 (length string) 'tags (erc-response.tags parsed)
string))
@ -4824,6 +4943,7 @@ Eventually add a # in front of it, if that turns it into a valid channel name."
rear-nonsticky erc-prompt field front-sticky read-only
;; stamp
cursor-intangible cursor-sensor-functions isearch-open-invisible
erc-stamp-type
;; match
invisible intangible
;; button
@ -5306,15 +5426,13 @@ and as second argument the event parsed as a vector."
(and (erc-is-message-ctcp-p message)
(not (string-match "^\C-aACTION.*\C-a$" message))))
(define-inline erc--get-speaker-bounds ()
"Return the bounds of `erc-speaker' property when present.
(defun erc--get-speaker-bounds ()
"Return the bounds of `erc-speaker' text property when present.
Assume buffer is narrowed to the confines of an inserted message."
(inline-quote
(and-let*
(((memq (get-text-property (point) 'erc-command) '(PRIVMSG NOTICE)))
(beg (or (and (get-text-property (point-min) 'erc-speaker) (point-min))
(next-single-property-change (point-min) 'erc-speaker))))
(cons beg (next-single-property-change beg 'erc-speaker)))))
(and-let* (((erc--check-msg-prop 'erc-msg 'msg))
(beg (text-property-not-all (point-min) (point-max)
'erc-speaker nil)))
(cons beg (next-single-property-change beg 'erc-speaker))))
(defvar erc--cmem-from-nick-function #'erc--cmem-get-existing
"Function maybe returning a \"channel member\" cons from a nick.
@ -5636,11 +5754,8 @@ See also `erc-display-message'."
(while queries
(let* ((type (upcase (car (split-string (car queries)))))
(hook (intern-soft (concat "erc-ctcp-query-" type "-hook")))
(erc-insert-pre-hook
(cons (lambda (s)
(put-text-property 0 (1- (length s)) 'erc-ctcp
(intern type) s))
erc-insert-pre-hook)))
(erc--msg-prop-overrides `((erc-msg . msg)
(erc-ctcp . ,(intern type)))))
(if (and hook (boundp hook))
(if (string-equal type "ACTION")
(run-hook-with-args-until-success
@ -6645,7 +6760,8 @@ ERC prints them as a single message joined by newlines.")
(when-let (((not (erc--input-split-abortp state)))
(inhibit-read-only t)
(old-buf (current-buffer)))
(progn ; unprogn this during next major surgery
(let ((erc--msg-prop-overrides '((erc-cmd . PRIVMSG)
(erc-msg . msg))))
(erc-set-active-buffer (current-buffer))
;; Kill the input and the prompt
(delete-region erc-input-marker (erc-end-of-input-line))
@ -6792,17 +6908,24 @@ Return non-nil only if we actually send anything."
(save-excursion
(erc--assert-input-bounds)
(let ((insert-position (marker-position (goto-char erc-insert-marker)))
(erc--msg-props (or erc--msg-props
(map-into (cons '(erc-msg . self)
erc--msg-prop-overrides)
'hash-table)))
beg)
(insert (erc-format-my-nick))
(setq beg (point))
(insert line)
(erc-put-text-property beg (point) 'font-lock-face 'erc-input-face)
(erc-put-text-property insert-position (point) 'erc-command 'PRIVMSG)
(insert "\n")
(save-restriction
(narrow-to-region insert-position (point))
(run-hooks 'erc-send-modify-hook)
(run-hooks 'erc-send-post-hook))
(run-hooks 'erc-send-post-hook)
(cl-assert (> (- (point-max) (point-min)) 1))
(add-text-properties (point-min) (1+ (point-min))
(erc--order-text-properties-from-hash
erc--msg-props)))
(erc--refresh-prompt)))))
(defun erc-command-symbol (command)
@ -8190,8 +8313,8 @@ This function should be on `erc-kill-channel-hook'."
(text-property-not-all (point-min) (point-max) 'erc-parsed nil))
(defun erc-restore-text-properties ()
"Restore the property `erc-parsed' for the region."
(when-let* ((parsed-posn (erc-find-parsed-property))
"Ensure the `erc-parsed' and `tags' props cover the entire message."
(when-let ((parsed-posn (erc-find-parsed-property))
(found (erc-get-parsed-vector parsed-posn)))
(put-text-property (point-min) (point-max) 'erc-parsed found)
(when-let ((tags (get-text-property parsed-posn 'tags)))
@ -8220,7 +8343,7 @@ This function should be on `erc-kill-channel-hook'."
See also `erc-message-type'."
;; IRC numerics are three-digit numbers, possibly with leading 0s.
;; To invert: (if (numberp o) (format "%03d" o) (symbol-name o))
(if-let* ((n (string-to-number command)) ((zerop n))) (intern command) n))
(if-let ((n (string-to-number command)) ((zerop n))) (intern command) n))
;; Teach url.el how to open irc:// URLs with ERC.
;; To activate, customize `url-irc-function' to `url-irc-erc'.

View file

@ -31,10 +31,14 @@
(defun erc-fill-tests--insert-privmsg (speaker &rest msg-parts)
(declare (indent 1))
(let ((msg (erc-format-privmessage speaker
(apply #'concat msg-parts) nil t)))
(put-text-property 0 (length msg) 'erc-command 'PRIVMSG msg)
(erc-display-message nil nil (current-buffer) msg)))
(let* ((msg (erc-format-privmessage speaker
(apply #'concat msg-parts) nil t))
;; (erc--msg-prop-overrides '((erc-msg . msg) (erc-cmd . PRIVMSG)))
(parsed (make-erc-response :unparsed msg :sender speaker
:command "PRIVMSG"
:command-args (list "#chan" msg)
:contents msg)))
(erc-display-message parsed nil (current-buffer) msg)))
(defun erc-fill-tests--wrap-populate (test)
(let ((original-window-buffer (window-buffer (selected-window)))
@ -111,6 +115,14 @@
(should (get-text-property (pos-bol) 'line-prefix))
(should (get-text-property (1- (pos-eol)) 'line-prefix))
(should-not (get-text-property (pos-eol) 'line-prefix))
;; Spans entire line uninterrupted.
(let* ((val (get-text-property (pos-bol) 'line-prefix))
(end (text-property-not-all (pos-bol) (point-max)
'line-prefix val)))
(when (and (/= end (pos-eol)) (= ?? (char-before end)))
(setq end (text-property-not-all (1+ end) (point-max)
'line-prefix val)))
(should (eq end (pos-eol))))
(should (equal (get-text-property (pos-bol) 'wrap-prefix)
'(space :width erc-fill--wrap-value)))
(should-not (get-text-property (pos-eol) 'wrap-prefix))
@ -145,7 +157,7 @@
(number-to-string erc-fill--wrap-value)
(prin1-to-string got))))
(with-current-buffer (generate-new-buffer name)
(push name erc-fill-tests--buffers)
(push (current-buffer) erc-fill-tests--buffers)
(with-silent-modifications
(insert (setq got (read repr))))
(erc-mode))
@ -153,15 +165,31 @@
(with-temp-file expect-file
(insert repr))
(if (file-exists-p expect-file)
;; Compare set-equal over intervals. This comparison is
;; less useful for messages treated by other modules because
;; it doesn't compare "nested" props belonging to
;; string-valued properties, like timestamps.
(should (equal-including-properties
(read repr)
(read (with-temp-buffer
;; Ensure string-valued properties, like timestamps, aren't
;; recursive (signals `max-lisp-eval-depth' exceeded).
(named-let assert-equal
((latest (read repr))
(expect (read (with-temp-buffer
(insert-file-contents-literally expect-file)
(buffer-string)))))
(pcase latest
((or "" 'nil) t)
((pred stringp)
(should (equal-including-properties latest expect))
(let ((latest-intervals (object-intervals latest))
(expect-intervals (object-intervals expect)))
(while-let ((l-iv (pop latest-intervals))
(x-iv (pop expect-intervals))
(l-tab (map-into (nth 2 l-iv) 'hash-table))
(x-tab (map-into (nth 2 x-iv) 'hash-table)))
(pcase-dolist (`(,l-k . ,l-v) (map-pairs l-tab))
(assert-equal l-v (gethash l-k x-tab))
(remhash l-k x-tab))
(should (zerop (hash-table-count x-tab))))))
((pred sequencep)
(assert-equal (seq-first latest) (seq-first expect))
(assert-equal (seq-rest latest) (seq-rest expect)))
(_ (should (equal latest expect)))))
(message "Snapshot file missing: %S" expect-file)))))
;; To inspect variable pitch, set `erc-mode-hook' to

View file

@ -81,6 +81,7 @@
(ert-deftest erc-scenarios-log--clear-stamp ()
:tags '(:expensive-test)
(require 'erc-stamp)
(erc-scenarios-common-with-cleanup
((erc-scenarios-common-dialog "base/assoc/bouncer-history")
(dumb-server (erc-d-run "localhost" t 'foonet))

View file

@ -55,7 +55,8 @@
:nick "tester")
;; Module `timestamp' follows `match' in insertion hooks.
(should (memq 'erc-add-timestamp
(memq 'erc-match-message erc-insert-modify-hook)))
(memq 'erc-match-message
(default-value 'erc-insert-modify-hook))))
;; The "match type" is `current-nick'.
(funcall expect 5 "tester")
(should (eq (get-text-property (1- (point)) 'font-lock-face)
@ -91,7 +92,8 @@
:nick "tester")
;; Module `timestamp' follows `match' in insertion hooks.
(should (memq 'erc-add-timestamp
(memq 'erc-match-message erc-insert-modify-hook)))
(memq 'erc-match-message
(default-value 'erc-insert-modify-hook))))
(funcall expect 5 "This server is in debug mode")))
(ert-info ("Ensure lines featuring \"bob\" are invisible")
@ -151,29 +153,13 @@
(= (next-single-property-change msg-beg 'invisible nil (pos-eol))
(pos-eol))))))))
(defun erc-scenarios-match--find-bol ()
(save-excursion
(should (get-text-property (1- (point)) 'erc-command))
(goto-char (should (previous-single-property-change (point) 'erc-command)))
(pos-bol)))
(defun erc-scenarios-match--find-eol ()
(save-excursion
(if-let ((next (next-single-property-change (point) 'erc-command)))
(goto-char next)
;; We're already at the end of the message.
(should (get-text-property (1- (point)) 'erc-command)))
(pos-eol)))
;; In most cases, `erc-hide-fools' makes line endings invisible.
(defun erc-scenarios-match--stamp-right-fools-invisible ()
:tags '(:expensive-test)
(let ((erc-insert-timestamp-function #'erc-insert-timestamp-right))
(erc-scenarios-match--invisible-stamp
(lambda ()
(let ((beg (erc-scenarios-match--find-bol))
(end (erc-scenarios-match--find-eol)))
(pcase-let ((`(,beg . ,end) (erc--get-inserted-msg-bounds)))
;; The end of the message is a newline.
(should (= ?\n (char-after end)))
@ -205,7 +191,7 @@
(should (= (next-single-property-change msg-end 'invisible) end)))))
(lambda ()
(let ((end (erc-scenarios-match--find-eol)))
(let ((end (erc--get-inserted-msg-bounds 'end)))
;; This message has a time stamp like all the others.
(should (eq (field-at-pos (1- end)) 'erc-timestamp))
@ -271,7 +257,172 @@
(let ((inv-beg (next-single-property-change (1- (pos-bol)) 'invisible)))
(should (eq (get-text-property inv-beg 'invisible) 'timestamp)))))))
(defun erc-scenarios-match--stamp-both-invisible-fill-static ()
(defun erc-scenarios-match--fill-wrap-stamp-dedented-p (point)
(pcase (get-text-property point 'line-prefix)
(`(space :width (- erc-fill--wrap-value (,n)))
(if (display-graphic-p) (< 100 n 200) (< 10 n 30)))
(`(space :width (- erc-fill--wrap-value ,n))
(< 10 n 30))))
(ert-deftest erc-scenarios-match--hide-fools/stamp-both/fill-wrap ()
;; Rewind the clock to known date artificially. We should probably
;; use a ticks/hz cons on 29+.
(let ((erc-stamp--current-time 704591940)
(erc-stamp--tz t)
(erc-fill-function #'erc-fill-wrap)
(bob-utterance-counter 0))
(erc-scenarios-match--invisible-stamp
(lambda ()
(ert-info ("Baseline check")
;; False date printed initially before anyone speaks.
(when (zerop bob-utterance-counter)
(save-excursion
(goto-char (point-min))
(search-forward "[Wed Apr 29 1992]")
;; First stamp in a buffer is not invisible from previous
;; newline (before stamp's own leading newline).
(should (= 4 (match-beginning 0)))
(should (get-text-property 3 'invisible))
(should-not (get-text-property 2 'invisible))
(should (erc-scenarios-match--fill-wrap-stamp-dedented-p 4))
(search-forward "[23:59]"))))
(ert-info ("Line endings in Bob's messages are invisible")
;; The message proper has the `invisible' property `match-fools'.
(should (eq (get-text-property (pos-bol) 'invisible) 'match-fools))
(pcase-let ((`(,mbeg . ,mend) (erc--get-inserted-msg-bounds)))
(should (= (char-after mend) ?\n))
(should-not (field-at-pos mend))
(should-not (field-at-pos mbeg))
(when (= bob-utterance-counter 1)
(let ((right-stamp (field-end mbeg)))
(should (eq 'erc-timestamp (field-at-pos right-stamp)))
(should (= mend (field-end right-stamp)))
(should (eq (field-at-pos (1- mend)) 'erc-timestamp))))
;; The `erc-ts' property is present in prop stack.
(should (get-text-property (pos-bol) 'erc-ts))
(should-not (next-single-property-change (1+ (pos-bol)) 'erc-ts))
;; Line ending has the `invisible' property `match-fools'.
(should (eq (get-text-property mbeg 'invisible) 'match-fools))
(should-not (get-text-property mend 'invisible))))
;; Only the message right after Alice speaks contains stamps.
(when (= 1 bob-utterance-counter)
(ert-info ("Date stamp occupying previous line is invisible")
(should (eq 'match-fools (get-text-property (point) 'invisible)))
(save-excursion
(forward-line -1)
(goto-char (pos-bol))
(should (looking-at (rx "[Mon May 4 1992]")))
(ert-info ("Stamp's NL `invisible' as fool, not timestamp")
(let ((end (match-end 0)))
(should (eq (char-after end) ?\n))
(should (eq 'timestamp
(get-text-property (1- end) 'invisible)))
(should (eq 'match-fools
(get-text-property end 'invisible)))))
(should (erc-scenarios-match--fill-wrap-stamp-dedented-p (point)))
;; Date stamp has a combined `invisible' property value
;; that starts at the previous message's trailing newline
;; and extends until the start of the message proper.
(should (equal ?\n (char-before (point))))
(should (equal ?\n (char-before (1- (point)))))
(let ((val (get-text-property (- (point) 2) 'invisible)))
(should (equal val 'timestamp))
(should (= (text-property-not-all (- (point) 2) (point-max)
'invisible val)
(pos-eol))))))
(ert-info ("Current message's RHS stamp is hidden")
;; Right stamp has `match-fools' property.
(save-excursion
(should-not (field-at-pos (point)))
(should (eq (field-at-pos (1- (pos-eol))) 'erc-timestamp)))
;; Stamp invisibility starts where message's ends.
(let ((msgend (next-single-property-change (pos-bol) 'invisible)))
;; Stamp has a combined `invisible' property value.
(should (equal (get-text-property msgend 'invisible)
'(timestamp match-fools)))
;; Combined `invisible' property spans entire timestamp.
(should (= (next-single-property-change msgend 'invisible)
(pos-eol))))))
(cl-incf bob-utterance-counter))
;; Alice.
(lambda ()
;; Set clock ahead a week or so.
(setq erc-stamp--current-time 704962800)
;; This message has no time stamp and is completely visible.
(should-not (eq (field-at-pos (1- (pos-eol))) 'erc-timestamp))
(should-not (next-single-property-change (pos-bol) 'invisible))))))
;; This asserts that speaker hiding by `erc-fill-wrap-merge' doesn't
;; take place after a series of hidden fool messages with an
;; intervening outgoing message followed immediately by a non-fool
;; message from the last non-hidden speaker (other than the user).
(ert-deftest erc-scenarios-match--hide-fools/stamp-both/fill-wrap/speak ()
(erc-scenarios-common-with-cleanup
((erc-scenarios-common-dialog "match/fools")
(erc-stamp--current-time 704591940)
(dumb-server (erc-d-run "localhost" t 'fill-wrap))
(erc-stamp--tz t)
(erc-fill-function #'erc-fill-wrap)
(port (process-contact dumb-server :service))
(erc-server-flood-penalty 0.1)
(erc-timestamp-only-if-changed-flag nil)
(erc-fools '("bob"))
(erc-text-matched-hook '(erc-hide-fools))
(erc-autojoin-channels-alist '((FooNet "#chan")))
(expect (erc-d-t-make-expecter)))
(ert-info ("Connect")
(with-current-buffer (erc :server "127.0.0.1"
:port port
:full-name "tester"
:password "changeme"
:nick "tester")
;; Module `timestamp' follows `match' in insertion hooks.
(should (memq 'erc-add-timestamp
(memq 'erc-match-message
(default-value 'erc-insert-modify-hook))))
(funcall expect 5 "This server is in debug mode")))
(ert-info ("Ensure lines featuring \"bob\" are invisible")
(with-current-buffer (erc-d-t-wait-for 10 (get-buffer "#chan"))
(should (funcall expect 10 "<alice> None better than"))
(should (funcall expect 10 "<alice> bob: Still we went"))
(should (funcall expect 10 "<bob> alice: Give me your hand"))
(erc-scenarios-common-say "hey")
(should (funcall expect 10 "<bob> You have paid the heavens"))
(should (funcall expect 10 "<alice> bob: In the sick air"))
(should (funcall expect 10 "<alice> The web of our life"))
;; Regression (see leading comment).
(should-not (equal "" (get-text-property (pos-bol) 'display)))
;; No remaining meta-data positions, no more timestamps.
(should-not (next-single-property-change (1+ (pos-bol)) 'erc-ts))
;; No remaining invisible messages.
(should-not (text-property-not-all (pos-bol) erc-insert-marker
'invisible nil))
(should (funcall expect 10 "ERC>"))
(should-not (get-text-property (pos-bol) 'invisible))
(should-not (get-text-property (point) 'invisible))))))
(defun erc-scenarios-match--stamp-both-invisible-fill-static (assert-ds)
(should (eq erc-insert-timestamp-function
#'erc-insert-timestamp-left-and-right))
@ -295,21 +446,20 @@
(ert-info ("Line endings in Bob's messages are invisible")
;; The message proper has the `invisible' property `match-fools'.
(should (eq (get-text-property (pos-bol) 'invisible) 'match-fools))
(let* ((mbeg (next-single-property-change (pos-bol) 'erc-command))
(mend (next-single-property-change mbeg 'erc-command)))
(pcase-let ((`(,mbeg . ,mend) (erc--get-inserted-msg-bounds)))
(if (/= 1 bob-utterance-counter)
(should (= (char-after mend) ?\n))
(should-not (field-at-pos mbeg))
(should-not (field-at-pos mend))
(when (= 1 bob-utterance-counter)
;; For Bob's stamped message, check newline after stamp.
(should (eq (field-at-pos mend) 'erc-timestamp))
(setq mend (field-end mend)))
(should (eq (field-at-pos (field-end mbeg)) 'erc-timestamp))
(should (eq (field-at-pos (1- mend)) 'erc-timestamp)))
;; The `erc-timestamp' property spans entire messages,
;; including stamps and filled text, which makes for
;; convenient traversal when `erc-stamp-mode' is enabled.
(should (get-text-property (pos-bol) 'erc-timestamp))
(should (= (next-single-property-change (pos-bol) 'erc-timestamp)
mend))
;; The `erc-ts' property is present in the message's
;; width 1 prop collection at its first char.
(should (get-text-property (pos-bol) 'erc-ts))
(should-not (next-single-property-change (1+ (pos-bol)) 'erc-ts))
;; Line ending has the `invisible' property `match-fools'.
(should (= (char-after mend) ?\n))
@ -327,12 +477,8 @@
(forward-line -1)
(goto-char (pos-bol))
(should (looking-at (rx "[Mon May 4 1992]")))
;; Date stamp has a combined `invisible' property value
;; that extends until the start of the message proper.
(should (equal (get-text-property (point) 'invisible)
'(timestamp match-fools)))
(should (= (next-single-property-change (point) 'invisible)
(1+ (pos-eol))))))
(should (= ?\n (char-after (- (point) 2)))) ; welcome!\n
(funcall assert-ds))) ; "assert date stamp"
(ert-info ("Folding preserved despite invisibility")
;; Message has a trailing time stamp, but it's been folded
@ -365,13 +511,45 @@
(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static ()
:tags '(:expensive-test)
(erc-scenarios-match--stamp-both-invisible-fill-static))
(erc-scenarios-match--stamp-both-invisible-fill-static
(lambda ()
;; Date stamp has an `invisible' property that starts from the
;; newline delimiting the current and previous messages and
;; extends until the stamp's final newline. It is not combined
;; with the old value, `match-fools'.
(let ((delim-pos (- (point) 2)))
(should (equal 'timestamp (get-text-property delim-pos 'invisible)))
;; Stamp-only invisibility ends before its last newline.
(should (= (text-property-not-all delim-pos (point-max)
'invisible 'timestamp)
(match-end 0))))))) ; pos-eol
(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static--nooffset ()
:tags '(:expensive-test)
(with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p))
(should-not erc-legacy-invisible-bounds-p)
(let ((erc-legacy-invisible-bounds-p t))
(erc-scenarios-match--stamp-both-invisible-fill-static))))
(erc-scenarios-match--stamp-both-invisible-fill-static
(lambda ()
;; Date stamp has an `invisible' property that covers its
;; format string exactly. It is not combined with the old
;; value, `match-fools'.
(let ((delim-prev (- (point) 2)))
(should-not (get-text-property delim-prev 'invisible))
(should (eq 'erc-timestamp (field-at-pos (point))))
(should (= (next-single-property-change delim-prev 'invisible)
(field-beginning (point))))
(should (equal 'timestamp
(get-text-property (1- (point)) 'invisible)))
;; Field stops before final newline because the date stamp
;; is (now, as of ERC 5.6) its own standalone message.
(should (= ?\n (char-after (field-end (point)))))
;; Stamp-only invisibility includes last newline.
(should (= (text-property-not-all (1- (point)) (point-max)
'invisible 'timestamp)
(1+ (field-end (point)))))))))))
;;; erc-scenarios-match.el ends here

View file

@ -279,7 +279,7 @@
(should-not erc-echo-timestamps)
(should-not erc-stamp--last-stamp)
(insert (propertize "abc" 'erc-timestamp 433483200))
(insert (propertize "a" 'erc-ts 433483200 'erc-msg 'msg) "bc")
(goto-char (point-min))
(let ((inhibit-message t)
(erc-echo-timestamp-format "%Y-%m-%d %H:%M:%S %Z")

View file

@ -292,6 +292,8 @@
(cl-incf counter))))
erc-accidental-paste-threshold-seconds
erc-insert-modify-hook
(erc-modules (remq 'stamp erc-modules))
(erc-send-input-line-function #'ignore)
(erc--input-review-functions erc--input-review-functions)
erc-send-completed-hook)
@ -356,7 +358,8 @@
(should (looking-back "#chan@ServNet 11> "))
(should (= (point) erc-input-marker))
(insert "/query bob")
(erc-send-current-line)
(let (erc-modules)
(erc-send-current-line))
;; Last command not inserted
(save-excursion (forward-line -1)
(should (looking-at "<tester> Howdy")))
@ -1431,6 +1434,44 @@
(should-not calls))))))
(ert-deftest erc--order-text-properties-from-hash ()
(let ((table (map-into '((a . 1)
(erc-ts . 0)
(erc-msg . s005)
(b . 2)
(erc-cmd . 5)
(c . 3))
'hash-table)))
(with-temp-buffer
(erc-mode)
(insert "abc\n")
(add-text-properties 1 2 (erc--order-text-properties-from-hash table))
(should (equal '( erc-msg s005
erc-ts 0
erc-cmd 5
a 1
b 2
c 3)
(text-properties-at (point-min)))))))
(ert-deftest erc--check-msg-prop ()
(let ((erc--msg-props (map-into '((a . 1) (b . x)) 'hash-table)))
(should (eq 1 (erc--check-msg-prop 'a)))
(should (erc--check-msg-prop 'a 1))
(should-not (erc--check-msg-prop 'a 2))
(should (eq 'x (erc--check-msg-prop 'b)))
(should (erc--check-msg-prop 'b 'x))
(should-not (erc--check-msg-prop 'b 1))
(should (erc--check-msg-prop 'a '(1 42)))
(should-not (erc--check-msg-prop 'a '(2 42)))
(let ((props '(42 x)))
(should (erc--check-msg-prop 'b props)))
(let ((v '(42 y)))
(should-not (erc--check-msg-prop 'b v)))))
(defmacro erc-tests--equal-including-properties (a b)
(list (if (< emacs-major-version 29)
'ert-equal-including-properties

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n<alice> one.\n<alice> two.\n<bob> three.\n<bob> four.\n<Dummy> five.\n<Dummy> six.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=(#7=(margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 436 454 (erc-timestamp 1680332400 line-prefix (space :width (- 27 (18))) field erc-timestamp) 454 455 (erc-timestamp 1680332400 field erc-timestamp) 455 456 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6=(space :width (- 27 (6))) erc-command PRIVMSG) 456 459 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 459 466 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 466 473 (erc-timestamp 1680332400 field erc-timestamp wrap-prefix #2# line-prefix #6# display #8=(#7# #("[07:00]" 0 7 (display #8# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 474 475 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9=(space :width (- 27 (8))) erc-command PRIVMSG) 475 480 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-command PRIVMSG) 480 486 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-command PRIVMSG) 487 488 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10=(space :width (- 27 0)) display #11="" erc-command PRIVMSG) 488 493 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# display #11# erc-command PRIVMSG) 493 495 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# display #11# erc-command PRIVMSG) 495 499 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 500 501 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12=(space :width (- 27 (6))) erc-command PRIVMSG) 501 504 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 504 512 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 513 514 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13=(space :width (- 27 0)) display #11# erc-command PRIVMSG) 514 517 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# display #11# erc-command PRIVMSG) 517 519 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# display #11# erc-command PRIVMSG) 519 524 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# erc-command PRIVMSG) 525 526 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14=(space :width (- 27 (8))) erc-command PRIVMSG) 526 531 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14# erc-command PRIVMSG) 531 538 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14# erc-command PRIVMSG) 539 540 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15=(space :width (- 27 0)) display #11# erc-command PRIVMSG) 540 545 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# display #11# erc-command PRIVMSG) 545 547 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# display #11# erc-command PRIVMSG) 547 551 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n<alice> one.\n<alice> two.\n<bob> three.\n<bob> four.\n<Dummy> five.\n<Dummy> six.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix (space :width (- 27 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 27 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display (#6=(margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 27 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#) 436 437 (erc-msg datestamp erc-ts 1680332400 field erc-timestamp) 437 454 (field erc-timestamp wrap-prefix #1# line-prefix (space :width (- 27 (18)))) 455 456 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #5=(space :width (- 27 (6)))) 456 459 (wrap-prefix #1# line-prefix #5#) 459 466 (wrap-prefix #1# line-prefix #5#) 466 473 (field erc-timestamp wrap-prefix #1# line-prefix #5# display (#6# #("[07:00]" 0 7 (invisible timestamp)))) 474 475 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #7=(space :width (- 27 (8)))) 475 480 (wrap-prefix #1# line-prefix #7#) 480 486 (wrap-prefix #1# line-prefix #7#) 487 488 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #8=(space :width (- 27 0)) display #9="") 488 493 (wrap-prefix #1# line-prefix #8# display #9#) 493 495 (wrap-prefix #1# line-prefix #8# display #9#) 495 499 (wrap-prefix #1# line-prefix #8#) 500 501 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #10=(space :width (- 27 (6)))) 501 504 (wrap-prefix #1# line-prefix #10#) 504 512 (wrap-prefix #1# line-prefix #10#) 513 514 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #11=(space :width (- 27 0)) display #9#) 514 517 (wrap-prefix #1# line-prefix #11# display #9#) 517 519 (wrap-prefix #1# line-prefix #11# display #9#) 519 524 (wrap-prefix #1# line-prefix #11#) 525 526 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #12=(space :width (- 27 (8)))) 526 531 (wrap-prefix #1# line-prefix #12#) 531 538 (wrap-prefix #1# line-prefix #12#) 539 540 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #13=(space :width (- 27 0)) display #9#) 540 545 (wrap-prefix #1# line-prefix #13# display #9#) 545 547 (wrap-prefix #1# line-prefix #13# display #9#) 547 551 (wrap-prefix #1# line-prefix #13#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n<alice> one.\n<alice> two.\n<bob> three.\n<bob> four.\n<Dummy> five.\n<Dummy> six.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 29 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 29) line-prefix #3=(space :width (- 29 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=(#7=(margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 29 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 29 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 436 454 (erc-timestamp 1680332400 line-prefix (space :width (- 29 (18))) field erc-timestamp) 454 455 (erc-timestamp 1680332400 field erc-timestamp) 455 456 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6=(space :width (- 29 (6))) erc-command PRIVMSG) 456 459 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 459 466 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 466 473 (erc-timestamp 1680332400 field erc-timestamp wrap-prefix #2# line-prefix #6# display #8=(#7# #("[07:00]" 0 7 (display #8# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 474 475 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9=(space :width (- 29 (8))) erc-command PRIVMSG) 475 480 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-command PRIVMSG) 480 486 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-command PRIVMSG) 487 488 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10=(space :width (- 29 0)) display #11="" erc-command PRIVMSG) 488 493 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# display #11# erc-command PRIVMSG) 493 495 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# display #11# erc-command PRIVMSG) 495 499 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 500 501 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12=(space :width (- 29 (6))) erc-command PRIVMSG) 501 504 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 504 512 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 513 514 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13=(space :width (- 29 0)) display #11# erc-command PRIVMSG) 514 517 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# display #11# erc-command PRIVMSG) 517 519 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# display #11# erc-command PRIVMSG) 519 524 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #13# erc-command PRIVMSG) 525 526 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14=(space :width (- 29 (8))) erc-command PRIVMSG) 526 531 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14# erc-command PRIVMSG) 531 538 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #14# erc-command PRIVMSG) 539 540 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15=(space :width (- 29 0)) display #11# erc-command PRIVMSG) 540 545 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# display #11# erc-command PRIVMSG) 545 547 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# display #11# erc-command PRIVMSG) 547 551 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #15# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n<alice> one.\n<alice> two.\n<bob> three.\n<bob> four.\n<Dummy> five.\n<Dummy> six.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 29) line-prefix (space :width (- 29 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 29 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display (#6=(margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 29 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 29 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#) 436 437 (erc-msg datestamp erc-ts 1680332400 field erc-timestamp) 437 454 (field erc-timestamp wrap-prefix #1# line-prefix (space :width (- 29 (18)))) 455 456 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #5=(space :width (- 29 (6)))) 456 459 (wrap-prefix #1# line-prefix #5#) 459 466 (wrap-prefix #1# line-prefix #5#) 466 473 (field erc-timestamp wrap-prefix #1# line-prefix #5# display (#6# #("[07:00]" 0 7 (invisible timestamp)))) 474 475 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #7=(space :width (- 29 (8)))) 475 480 (wrap-prefix #1# line-prefix #7#) 480 486 (wrap-prefix #1# line-prefix #7#) 487 488 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #8=(space :width (- 29 0)) display #9="") 488 493 (wrap-prefix #1# line-prefix #8# display #9#) 493 495 (wrap-prefix #1# line-prefix #8# display #9#) 495 499 (wrap-prefix #1# line-prefix #8#) 500 501 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #10=(space :width (- 29 (6)))) 501 504 (wrap-prefix #1# line-prefix #10#) 504 512 (wrap-prefix #1# line-prefix #10#) 513 514 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #11=(space :width (- 29 0)) display #9#) 514 517 (wrap-prefix #1# line-prefix #11# display #9#) 517 519 (wrap-prefix #1# line-prefix #11# display #9#) 519 524 (wrap-prefix #1# line-prefix #11#) 525 526 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #12=(space :width (- 29 (8)))) 526 531 (wrap-prefix #1# line-prefix #12#) 531 538 (wrap-prefix #1# line-prefix #12#) 539 540 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #13=(space :width (- 29 0)) display #9#) 540 545 (wrap-prefix #1# line-prefix #13# display #9#) 545 547 (wrap-prefix #1# line-prefix #13# display #9#) 547 551 (wrap-prefix #1# line-prefix #13#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n* bob one\n<bob> two.\n* bob three\n<bob> four.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=(#7=(margin right-margin) #("[00:00]" 0 7 (display #1# invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 436 454 (erc-timestamp 1680332400 line-prefix (space :width (- 27 (18))) field erc-timestamp) 454 455 (erc-timestamp 1680332400 field erc-timestamp) 455 456 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6=(space :width (- 27 (6))) erc-command PRIVMSG) 456 459 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 459 466 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 466 473 (erc-timestamp 1680332400 field erc-timestamp wrap-prefix #2# line-prefix #6# display #8=(#7# #("[07:00]" 0 7 (display #8# invisible timestamp font-lock-face erc-timestamp-face)))) 474 476 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9=(space :width (- 27 (6))) erc-ctcp ACTION erc-command PRIVMSG) 476 479 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-ctcp ACTION erc-command PRIVMSG) 479 483 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #9# erc-ctcp ACTION erc-command PRIVMSG) 484 485 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10=(space :width (- 27 (6))) erc-command PRIVMSG) 485 488 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 488 494 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #10# erc-command PRIVMSG) 495 497 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11=(space :width (- 27 (2))) erc-ctcp ACTION erc-command PRIVMSG) 497 500 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11# erc-ctcp ACTION erc-command PRIVMSG) 500 506 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #11# erc-ctcp ACTION erc-command PRIVMSG) 507 508 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12=(space :width (- 27 (6))) erc-command PRIVMSG) 508 511 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG) 511 518 (erc-timestamp 1680332400 wrap-prefix #2# line-prefix #12# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n\n[Sat Apr 1 2023]\n<bob> zero.[07:00]\n* bob one\n<bob> two.\n* bob three\n<bob> four.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix (space :width (- 27 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 27 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display (#6=(margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 27 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#) 436 437 (erc-msg datestamp erc-ts 1680332400 field erc-timestamp) 437 454 (field erc-timestamp wrap-prefix #1# line-prefix (space :width (- 27 (18)))) 455 456 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #5=(space :width (- 27 (6)))) 456 459 (wrap-prefix #1# line-prefix #5#) 459 466 (wrap-prefix #1# line-prefix #5#) 466 473 (field erc-timestamp wrap-prefix #1# line-prefix #5# display (#6# #("[07:00]" 0 7 (invisible timestamp)))) 474 475 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG erc-ctcp ACTION wrap-prefix #1# line-prefix #7=(space :width (- 27 (6)))) 475 476 (wrap-prefix #1# line-prefix #7#) 476 479 (wrap-prefix #1# line-prefix #7#) 479 483 (wrap-prefix #1# line-prefix #7#) 484 485 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #8=(space :width (- 27 0)) display #9="") 485 488 (wrap-prefix #1# line-prefix #8# display #9#) 488 490 (wrap-prefix #1# line-prefix #8# display #9#) 490 494 (wrap-prefix #1# line-prefix #8#) 495 496 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG erc-ctcp ACTION wrap-prefix #1# line-prefix #10=(space :width (- 27 (2)))) 496 497 (wrap-prefix #1# line-prefix #10#) 497 500 (wrap-prefix #1# line-prefix #10#) 500 506 (wrap-prefix #1# line-prefix #10#) 507 508 (erc-msg msg erc-ts 1680332400 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #11=(space :width (- 27 0)) display #9#) 508 511 (wrap-prefix #1# line-prefix #11# display #9#) 511 513 (wrap-prefix #1# line-prefix #11# display #9#) 513 518 (wrap-prefix #1# line-prefix #11#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=((margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix (space :width (- 27 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 27 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display ((margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 27 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 29 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 29) line-prefix #3=(space :width (- 29 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=((margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 29 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 29 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 29) line-prefix (space :width (- 29 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 29 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display ((margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 29 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 29 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 25 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 25) line-prefix #3=(space :width (- 25 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=((margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 25 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 25 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 25) line-prefix (space :width (- 25 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 25 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display ((margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 25 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 25 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=((margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix (space :width (- 27 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 27 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display ((margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 191 192 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 349 350 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG wrap-prefix #1# line-prefix #4=(space :width (- 27 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#))

View file

@ -1 +1 @@
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n<bob> This buffer is for text.\n*** one two three\n*** four five six\n<bob> Somebody stop me\n" 2 20 (erc-timestamp 0 line-prefix (space :width (- 27 (18))) field erc-timestamp) 20 21 (erc-timestamp 0 field erc-timestamp) 21 183 (erc-timestamp 0 wrap-prefix #2=(space :width 27) line-prefix #3=(space :width (- 27 (4)))) 183 190 (erc-timestamp 0 field erc-timestamp wrap-prefix #2# line-prefix #3# display #1=((margin right-margin) #("[00:00]" 0 7 (display #1# isearch-open-invisible timestamp invisible timestamp font-lock-face erc-timestamp-face)))) 190 191 (line-spacing 0.5) 191 192 (erc-timestamp 0 wrap-prefix #2# line-prefix #4=(space :width (- 27 (8))) erc-command PRIVMSG) 192 197 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 197 199 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 199 202 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 202 315 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 315 316 (erc-timestamp 0 erc-command PRIVMSG) 316 348 (erc-timestamp 0 wrap-prefix #2# line-prefix #4# erc-command PRIVMSG) 348 349 (line-spacing 0.5) 349 350 (erc-timestamp 0 wrap-prefix #2# line-prefix #5=(space :width (- 27 (6))) erc-command PRIVMSG) 350 353 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 353 355 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 355 360 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 360 435 (erc-timestamp 0 wrap-prefix #2# line-prefix #5# erc-command PRIVMSG) 435 436 (line-spacing 0.5) 436 437 (erc-timestamp 0 wrap-prefix #2# line-prefix #6=(space :width (- 27 0)) display #7="" erc-command PRIVMSG) 437 440 (erc-timestamp 0 wrap-prefix #2# line-prefix #6# display #7# erc-command PRIVMSG) 440 442 (erc-timestamp 0 wrap-prefix #2# line-prefix #6# display #7# erc-command PRIVMSG) 442 466 (erc-timestamp 0 wrap-prefix #2# line-prefix #6# erc-command PRIVMSG) 466 467 (line-spacing 0.5) 467 484 (erc-timestamp 0 wrap-prefix #2# line-prefix (space :width (- 27 (4)))) 485 502 (erc-timestamp 0 wrap-prefix #2# line-prefix (space :width (- 27 (4)))) 502 503 (line-spacing 0.5) 503 504 (erc-timestamp 0 wrap-prefix #2# line-prefix #8=(space :width (- 27 (6))) erc-command PRIVMSG) 504 507 (erc-timestamp 0 wrap-prefix #2# line-prefix #8# erc-command PRIVMSG) 507 525 (erc-timestamp 0 wrap-prefix #2# line-prefix #8# erc-command PRIVMSG))
#("\n\n\n[Thu Jan 1 1970]\n*** 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.[00:00]\n<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n<bob> This buffer is for text.\n*** one two three\n*** four five six\n<bob> Somebody stop me\n" 2 3 (erc-msg datestamp erc-ts 0 field erc-timestamp) 3 20 (field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix (space :width (- 27 (18)))) 21 22 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #2=(space :width (- 27 (4)))) 22 183 (wrap-prefix #1# line-prefix #2#) 183 190 (field erc-timestamp wrap-prefix #1# line-prefix #2# display ((margin right-margin) #("[00:00]" 0 7 (invisible timestamp)))) 190 191 (line-spacing 0.5) 191 192 (erc-msg msg erc-cmd PRIVMSG erc-ts 0 wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 192 197 (wrap-prefix #1# line-prefix #3#) 197 199 (wrap-prefix #1# line-prefix #3#) 199 202 (wrap-prefix #1# line-prefix #3#) 202 315 (wrap-prefix #1# line-prefix #3#) 316 348 (wrap-prefix #1# line-prefix #3#) 348 349 (line-spacing 0.5) 349 350 (erc-msg msg erc-cmd PRIVMSG erc-ts 0 wrap-prefix #1# line-prefix #4=(space :width (- 27 (6)))) 350 353 (wrap-prefix #1# line-prefix #4#) 353 355 (wrap-prefix #1# line-prefix #4#) 355 360 (wrap-prefix #1# line-prefix #4#) 360 435 (wrap-prefix #1# line-prefix #4#) 435 436 (line-spacing 0.5) 436 437 (erc-msg msg erc-cmd PRIVMSG erc-ts 0 wrap-prefix #1# line-prefix #5=(space :width (- 27 0)) display #6="") 437 440 (wrap-prefix #1# line-prefix #5# display #6#) 440 442 (wrap-prefix #1# line-prefix #5# display #6#) 442 466 (wrap-prefix #1# line-prefix #5#) 466 467 (line-spacing 0.5) 467 468 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #7=(space :width (- 27 (4)))) 468 484 (wrap-prefix #1# line-prefix #7#) 485 486 (erc-msg unknown erc-ts 0 wrap-prefix #1# line-prefix #8=(space :width (- 27 (4)))) 486 502 (wrap-prefix #1# line-prefix #8#) 502 503 (line-spacing 0.5) 503 504 (erc-msg msg erc-cmd PRIVMSG erc-ts 0 wrap-prefix #1# line-prefix #9=(space :width (- 27 (6)))) 504 507 (wrap-prefix #1# line-prefix #9#) 507 525 (wrap-prefix #1# line-prefix #9#))

View file

@ -1 +1 @@
#("\n\n[00:00]*** 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.\n[00:00]<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n[00:00]<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 9 (erc-timestamp 0 display (#4=(margin left-margin) #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix #2=(space :width (- 27 (4)))) 9 171 (erc-timestamp 0 wrap-prefix #1# line-prefix #2#) 172 179 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #3=(space :width (- 27 (8)))) 179 180 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 180 185 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 185 187 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 187 190 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 190 303 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 303 304 (erc-timestamp 0 erc-command PRIVMSG) 304 336 (erc-timestamp 0 wrap-prefix #1# line-prefix #3# erc-command PRIVMSG) 337 344 (erc-timestamp 0 display (#4# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #5=(space :width (- 27 (6)))) 344 345 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 345 348 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 348 350 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 350 355 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG) 355 430 (erc-timestamp 0 wrap-prefix #1# line-prefix #5# erc-command PRIVMSG))
#("\n\n[00:00]*** 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.\n[00:00]<alice> bob: come, you are a tedious fool: to the purpose. What was done to Elbow's wife, that he hath cause to complain of? Come me to what was done to her.\n[00:00]<bob> alice: Either your unparagoned mistress is dead, or she's outprized by a trifle.\n" 2 3 (erc-msg unknown erc-ts 0 display #3=(#5=(margin left-margin) #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1=(space :width 27) line-prefix #2=(space :width (- 27 (4)))) 3 9 (display #3# field erc-timestamp wrap-prefix #1# line-prefix #2#) 9 171 (wrap-prefix #1# line-prefix #2#) 172 173 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG display #6=(#5# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #4=(space :width (- 27 (8)))) 173 179 (display #6# field erc-timestamp wrap-prefix #1# line-prefix #4#) 179 180 (wrap-prefix #1# line-prefix #4#) 180 185 (wrap-prefix #1# line-prefix #4#) 185 187 (wrap-prefix #1# line-prefix #4#) 187 190 (wrap-prefix #1# line-prefix #4#) 190 303 (wrap-prefix #1# line-prefix #4#) 304 336 (wrap-prefix #1# line-prefix #4#) 337 338 (erc-msg msg erc-ts 0 erc-cmd PRIVMSG display #8=(#5# #("[00:00]" 0 7 (invisible timestamp font-lock-face erc-timestamp-face))) field erc-timestamp wrap-prefix #1# line-prefix #7=(space :width (- 27 (6)))) 338 344 (display #8# field erc-timestamp wrap-prefix #1# line-prefix #7#) 344 345 (wrap-prefix #1# line-prefix #7#) 345 348 (wrap-prefix #1# line-prefix #7#) 348 350 (wrap-prefix #1# line-prefix #7#) 350 355 (wrap-prefix #1# line-prefix #7#) 355 430 (wrap-prefix #1# line-prefix #7#))

View file

@ -0,0 +1,41 @@
;; -*- mode: lisp-data; -*-
((pass 10 "PASS :changeme"))
((nick 1 "NICK tester"))
((user 1 "USER user 0 * :tester")
(0 ":irc.foonet.org 001 tester :Welcome to the foonet IRC Network tester")
(0 ":irc.foonet.org 002 tester :Your host is irc.foonet.org, running version oragono-2.6.0-7481bf0385b95b16")
(0 ":irc.foonet.org 003 tester :This server was created Tue, 04 May 2021 05:06:18 UTC")
(0 ":irc.foonet.org 004 tester irc.foonet.org oragono-2.6.0-7481bf0385b95b16 BERTZios CEIMRUabefhiklmnoqstuv Iabefhkloqv")
(0 ":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 ":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:1,WHOIS:1,USERHOST:10,PRIVMSG:4,TAGMSG:4,NOTICE:4,MONITOR:100 TOPICLEN=390 UTF8MAPPING=rfc8265 UTF8ONLY WHOX :are supported by this server")
(0 ":irc.foonet.org 005 tester draft/CHATHISTORY=100 :are supported by this server")
(0 ":irc.foonet.org 251 tester :There are 0 users and 3 invisible on 1 server(s)")
(0 ":irc.foonet.org 252 tester 0 :IRC Operators online")
(0 ":irc.foonet.org 253 tester 0 :unregistered connections")
(0 ":irc.foonet.org 254 tester 1 :channels formed")
(0 ":irc.foonet.org 255 tester :I have 3 clients and 0 servers")
(0 ":irc.foonet.org 265 tester 3 3 :Current local users 3, max 3")
(0 ":irc.foonet.org 266 tester 3 3 :Current global users 3, max 3")
(0 ":irc.foonet.org 422 tester :MOTD File is missing"))
((mode-user 10 "MODE tester +i")
(0 ":irc.foonet.org 221 tester +i")
(0 ":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."))
((join 6 "JOIN #chan")
(0 ":tester!~u@9g6b728983yd2.irc JOIN #chan")
(0 ":irc.foonet.org 353 tester = #chan :alice tester @bob")
(0 ":irc.foonet.org 366 tester #chan :End of NAMES list"))
((mode 5 "MODE #chan")
(0 ":irc.foonet.org 324 tester #chan +nt")
(0 ":irc.foonet.org 329 tester #chan 1620104779")
(0.1 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!")
(0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :None better than to let him fetch off his drum, which you hear him so confidently undertake to do.")
(0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: Still we went coupled and inseparable.")
(0 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :alice: Give me your hand. This hand is moist, my lady."))
((privmsg 5 "PRIVMSG #chan :hey")
(0 ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :You have paid the heavens your function, and the prisoner the very debt of your calling. I have laboured for the poor gentleman to the extremest shore of my modesty; but my brother justice have I found so severe, that he hath forced me to tell him he is indeed Justice.")
(0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :bob: In the sick air: let not thy sword skip one.")
(0 ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :The web of our life is of a mingled yarn, good and ill together: our virtues would be proud if our faults whipped them not; and our crimes would despair if they were not cherished by our virtues."))