From aae534bcbe0eb75e436c428b248a87748ec185b6 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sat, 8 Jul 2023 07:06:09 -0700 Subject: [PATCH 0/4] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (4): [5.6] Respect existing invisibility props in erc-stamp [5.6] Simplify erc-button-add-nickname-buttons [5.6] Add text props for CTCPs and speakers in ERC [5.6] Handle composite faces better in erc-display-message etc/ERC-NEWS | 29 ++- lisp/erc/erc-backend.el | 39 ++-- lisp/erc/erc-button.el | 78 ++++---- lisp/erc/erc-dcc.el | 16 +- lisp/erc/erc-fill.el | 25 ++- lisp/erc/erc-match.el | 29 +-- lisp/erc/erc-sasl.el | 8 +- lisp/erc/erc-stamp.el | 21 ++- lisp/erc/erc-track.el | 12 +- lisp/erc/erc.el | 99 +++++++--- test/lisp/erc/erc-button-tests.el | 2 +- test/lisp/erc/erc-fill-tests.el | 5 +- test/lisp/erc/erc-scenarios-match.el | 259 ++++++++++++++++++++++++--- 13 files changed, 467 insertions(+), 155 deletions(-) Interdiff: diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 40bcd934772..795553f1666 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -144,11 +144,12 @@ the same effect by issuing a "/CLEAR" at the prompt. Some minor quality-of-life niceties have finally made their way to ERC. For example, the function 'erc-echo-timestamp' is now interactive and can be invoked on any message to view its timestamp in -the echo area. The command 'erc-button-previous' now moves to the -beginning instead of the end of buttons. A new command, 'erc-news', -can now be invoked to visit this very file. And the 'irccontrols' -module now supports additional colors and special handling for -"spoilers" (hidden text). +the echo area. Fool visibility has become togglable with the new +command 'erc-match-toggle-hidden-fools'. The 'button' module's +'erc-button-previous' now moves to the beginning instead of the end of +buttons. A new command, 'erc-news', can be invoked to visit this very +file. And the 'irccontrols' module now supports additional colors and +special handling for "spoilers" (hidden text). ** Changes in the library API. @@ -197,6 +198,9 @@ traversing messages. To compensate, a new property, 'erc-timestamp', now spans message bodies but not the newlines delimiting them. Somewhat relatedly, the function 'erc-insert-aligned' has been deprecated and removed from the primary client code path. +Additionally, the 'stamp' module now merges its 'invisible' property +with existing ones, when present, and it includes all white space +around stamps when doing so. *** The role of a module's Custom group is now more clearly defined. Associating built-in modules with Custom groups and provided library diff --git a/lisp/erc/erc-match.el b/lisp/erc/erc-match.el index 549de4feeb8..a5b0af41b2a 100644 --- a/lisp/erc/erc-match.el +++ b/lisp/erc/erc-match.el @@ -660,6 +660,10 @@ erc-match--hide-fools-offset-bounds (defun erc-hide-fools (match-type _nickuserhost _message) "Hide comments from designated fools." (when (eq match-type 'fool) + (erc-match--hide-message))) + +(defun erc-match--hide-message () + (progn ; FIXME raise sexp (if erc-match--hide-fools-offset-bounds (let ((beg (point-min)) (end (point-max))) @@ -677,12 +681,21 @@ erc-beep-on-match (beep))) (defun erc-match--modify-invisibility-spec () - "Add an ellipsis property to the local spec." + "Add an `erc-match' property to the local spec." (if erc-match-mode (add-to-invisibility-spec 'erc-match) (erc-with-all-buffers-of-server nil nil (remove-from-invisibility-spec 'erc-match)))) +(defun erc-match-toggle-hidden-fools () + "Toggle fool visibility. +Expect `erc-hide-fools' or a function that does something similar +to be in `erc-text-matched-hook'." + (interactive) + (if (memq 'erc-match (ensure-list buffer-invisibility-spec)) + (remove-from-invisibility-spec 'erc-match) + (add-to-invisibility-spec 'erc-match))) + (provide 'erc-match) ;;; erc-match.el ends here diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index 2f52d78d42b..83ee4a200ed 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -437,6 +437,7 @@ erc-insert-timestamp-right (goto-char (point-max)) (forward-char -1) ; before the last newline (let* ((str-width (string-width string)) + (buffer-invisibility-spec nil) ; `current-column' > 0 window ; used in computation of `pos' only (pos (cond (erc-timestamp-right-column erc-timestamp-right-column) diff --git a/test/lisp/erc/erc-scenarios-match.el b/test/lisp/erc/erc-scenarios-match.el index edc1749cdd2..715fe9c25d7 100644 --- a/test/lisp/erc/erc-scenarios-match.el +++ b/test/lisp/erc/erc-scenarios-match.el @@ -24,8 +24,11 @@ (let ((load-path (cons (ert-resource-directory) load-path))) (require 'erc-scenarios-common))) -(require 'erc-stamp) -(require 'erc-match) +(eval-when-compile + (require 'erc-join) + (require 'erc-stamp) + (require 'erc-match)) + (require 'erc-fill) ;; This defends against a regression in which all matching by the @@ -62,6 +65,9 @@ erc-scenarios-match--stamp-left-current-nick ;; interactively, and check for wierdness before and after doing ;; M-: (remove-from-invisibility-spec 'erc-match) RET. (defun erc-scenarios-match--invisible-stamp (hiddenp visiblep) + (unless noninteractive + (kill-new "(remove-from-invisibility-spec 'erc-match)")) + (erc-scenarios-common-with-cleanup ((erc-scenarios-common-dialog "join/legacy") (dumb-server (erc-d-run "localhost" t 'foonet)) @@ -236,6 +242,93 @@ erc-scenarios-match--stamp-right-invisible-fill-wrap (let ((inv-beg (next-single-property-change (1- (pos-bol)) 'invisible))) (should (eq (get-text-property inv-beg 'invisible) 'timestamp))))))) -(eval-when-compile (require 'erc-join)) +(ert-deftest erc-scenarios-match--stamp-both-invisible-fill-static () + :tags '(:expensive-test) + (should (eq erc-insert-timestamp-function + #'erc-insert-timestamp-left-and-right)) + + ;; Rewind the clock to known date artificially. + (let ((erc-stamp--current-time 704591940) + (erc-stamp--tz t) + (erc-fill-function #'erc-fill-static) + (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]") + (search-forward "[23:59]")))) + + (ert-info ("Line endings in Bob's messages are invisible") + ;; The message proper has the `invisible' property `erc-match'. + (should (eq (get-text-property (pos-bol) 'invisible) 'erc-match)) + (let* ((mbeg (next-single-property-change (pos-bol) 'erc-command)) + (mend (next-single-property-change mbeg 'erc-command))) + + (if (/= 1 bob-utterance-counter) + (should-not (field-at-pos mend)) + ;; For Bob's stamped message, check newline after stamp. + (should (eq (field-at-pos mend) 'erc-timestamp)) + (setq mend (field-end mend))) + + ;; 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)) + + ;; Line ending has the `invisible' property `erc-match'. + (should (= (char-after mend) ?\n)) + (should (eq (get-text-property mend'invisible) 'erc-match)))) + + ;; Only the message right after Alice speaks contains stamps. + (when (= 1 bob-utterance-counter) + + (ert-info ("Date stamp occupying previous line is invisible") + (save-excursion + (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 erc-match))) + (should (= (next-single-property-change (point) 'invisible) + (1+ (pos-eol)))))) + + (ert-info ("Folding preserved despite invisibility") + ;; Message has a trailing time stamp, but it's been folded + ;; over to the next line. + (should-not (eq (field-at-pos (1- (pos-eol))) 'erc-timestamp)) + (save-excursion + (forward-line) + (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 erc-match))) + + ;; Combined `invisible' property spans entire timestamp. + (should (= (next-single-property-change msgend 'invisible) + (save-excursion (forward-line) (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)))))) ;;; erc-scenarios-match.el ends here -- 2.41.0