From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: "J.P." Newsgroups: gmane.emacs.bugs Subject: bug#51969: 29.0.50; Add command for refilling ERC buffers Date: Fri, 19 Nov 2021 20:12:13 -0800 Message-ID: <87fsrrqxcy.fsf__29180.3152345651$1637381603$gmane$org@neverwas.me> References: <87bl2gjuo9.fsf@neverwas.me> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="27701"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.60 (gnu/linux) Cc: emacs-erc@gnu.org To: 51969@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Sat Nov 20 05:13:15 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1moHkY-0006yZ-K9 for geb-bug-gnu-emacs@m.gmane-mx.org; Sat, 20 Nov 2021 05:13:14 +0100 Original-Received: from localhost ([::1]:57756 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1moHkW-00067W-OB for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 19 Nov 2021 23:13:12 -0500 Original-Received: from eggs.gnu.org ([209.51.188.92]:55026) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1moHkM-00067G-On for bug-gnu-emacs@gnu.org; Fri, 19 Nov 2021 23:13:02 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:57827) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1moHkM-00075R-Gl for bug-gnu-emacs@gnu.org; Fri, 19 Nov 2021 23:13:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1moHkM-0007EL-70 for bug-gnu-emacs@gnu.org; Fri, 19 Nov 2021 23:13:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: "J.P." Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 20 Nov 2021 04:13:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 51969 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 51969-submit@debbugs.gnu.org id=B51969.163738155227750 (code B ref 51969); Sat, 20 Nov 2021 04:13:02 +0000 Original-Received: (at 51969) by debbugs.gnu.org; 20 Nov 2021 04:12:32 +0000 Original-Received: from localhost ([127.0.0.1]:41140 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moHjr-0007DU-BY for submit@debbugs.gnu.org; Fri, 19 Nov 2021 23:12:32 -0500 Original-Received: from mail-108-mta185.mxroute.com ([136.175.108.185]:40297) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1moHjn-0007DB-UO for 51969@debbugs.gnu.org; Fri, 19 Nov 2021 23:12:29 -0500 Original-Received: from filter004.mxroute.com ([149.28.56.236] filter004.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta185.mxroute.com (ZoneMTA) with ESMTPSA id 17d3b8b7c68000177f.001 for <51969@debbugs.gnu.org> (version=TLSv1/SSLv3 cipher=ECDHE-RSA-AES128-GCM-SHA256); Sat, 20 Nov 2021 04:12:16 +0000 X-Zone-Loop: 658bda79c441a625b37d7073df79d0a712a78c52e164 X-Originating-IP: [149.28.56.236] DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=neverwas.me ; s=x; h=Content-Type:MIME-Version:Message-ID:In-Reply-To:Date:References: Subject:Cc:To:From:Sender:Reply-To:Content-Transfer-Encoding:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=3uN2FqIuBdjDX/yVf45I/Zioz6NwMMQNw19RV9SlDWY=; b=M181DvC/tvNrMZhvjIPijN8xmZ EXsdYdxqYPiX+def/CydonE0VZWSdtAFd9zJt469MmCj4ArrjSFL3sXOPRn8knCc3vb4tIwxkjFfX UBZ3F2umshy9+2yrEYhDhhCt/oBk6dzxDKRSpcR37tFQZTaJc9m+38aEKujEe8tRu8c9aiRoKLBqy rpRBb+aFTySIcqSri3f0QKp2bjUFCcML646L17WhRRcFhRzo+f6wg5usoSCxUzvdlE4GgQcIJ4qlG 0DXc3awIfsXJqxIvlGzqHa08OI+8H7V7j1gUFEwGDbCYH3F4qviKGvj3NFIgPADLM8awyQysv9Jua nqPAZ95g==; In-Reply-To: <87bl2gjuo9.fsf@neverwas.me> (J. P.'s message of "Fri, 19 Nov 2021 02:39:50 -0800") X-AuthUser: masked@neverwas.me X-Zone-Spam-Resolution: no action X-Zone-Spam-Status: No, score=-0.1, required=15, tests=[ARC_NA=0, RCPT_COUNT_TWO=0, FROM_HAS_DN=0, HAS_ATTACHMENT=0, FROM_EQ_ENVFROM=0, MIME_TRACE=0, MIME_GOOD=-0.1, TO_DN_NONE=0, MID_RHS_MATCH_FROM=0, RCVD_COUNT_ZERO=0, NEURAL_SPAM=0] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:220445 Archived-At: --=-=-= Content-Type: text/plain Addressed some erroneous line folding involving wide chars. But bugs likely remain. --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0000-v2-v3.diff Content-Transfer-Encoding: quoted-printable >From 1058b9202f9b530062bd5268c81a111976db61f2 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Fri, 19 Nov 2021 19:07:24 -0800 Subject: NOT A PATCH F. Jason Park (1): Add command to refill ERC buffers lisp/erc/erc-fill.el | 121 ++++++++++ .../erc/erc-fill-resources/static-60.buffer | 24 ++ .../erc/erc-fill-resources/static-72.buffer | 20 ++ .../erc/erc-fill-resources/variable-60.buffer | 18 ++ .../erc/erc-fill-resources/variable-72.buffer | 18 ++ test/lisp/erc/erc-fill-tests.el | 206 ++++++++++++++++++ 6 files changed, 407 insertions(+) create mode 100644 test/lisp/erc/erc-fill-resources/static-60.buffer create mode 100644 test/lisp/erc/erc-fill-resources/static-72.buffer create mode 100644 test/lisp/erc/erc-fill-resources/variable-60.buffer create mode 100644 test/lisp/erc/erc-fill-resources/variable-72.buffer create mode 100644 test/lisp/erc/erc-fill-tests.el Interdiff: diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el index 3bf335d098..49130b9ffc 100644 --- a/lisp/erc/erc-fill.el +++ b/lisp/erc/erc-fill.el @@ -112,30 +112,47 @@ erc-fill-column "The column at which a filled paragraph is broken." :type 'integer) =20 -(defun erc-fill--remove-stamp-right () - (goto-char (point-min)) - (let (changed) - (while - (when-let* ((nextf (next-single-property-change (point) 'field))) - (goto-char (field-end nextf t)) - ;; Sweep up residual phantom field remants - (delete-region nextf (field-end nextf t)) - (setq changed t))) - changed)) - -(defun erc-fill--remove-stamp-left () - "Remove at most one LEFT or one right timestamp, if any." - (goto-char (point-min)) - ;; FIXME actually, it may be a mistake to blow past white space - ;; without checking for intervening intervals that need cleaning up. - (when-let* ((beg (save-excursion (skip-syntax-forward ">-") (point))) - (nextf (when (eq 'erc-timestamp (field-at-pos beg)) - (field-beginning beg t))) - ((eq 'erc-timestamp (get-text-property nextf 'field)))) - (goto-char (field-end nextf t)) - (skip-syntax-forward "-") - (delete-region nextf (point)) - t)) +(defun erc-fill--refill-message (beg end) + "Refill but don't re-stamp region between BEG and END. +Return non-nil if timestamps were removed." + (let (left-changed right-changed) + (narrow-to-region beg end) + ;; Remove at most one left timestamp, if any. + (goto-char (point-min)) + (setq left-changed + ;; FIXME it may be a mistake to blow past leading whitespace + ;; without removing any intervening ws-only field intervals + (when-let* ((beg (save-excursion (skip-syntax-forward ">-") (poi= nt))) + (nextf (when (eq 'erc-timestamp (field-at-pos beg)) + (field-beginning beg t))) + ((eq 'erc-timestamp (get-text-property nextf 'field)= ))) + (goto-char (field-end nextf t)) + (skip-syntax-forward "-") + (delete-region nextf (point)) + t)) + ;; Get everything on one line (if NOSQUEEZE seems warranted, see + ;; note below re ASCII art). + (let ((fill-column (string-width (buffer-string)))) + (fill-region (point-min) (point-max))) + ;; Remove any stamps from right-hand side. + (goto-char (point-min)) + (setq right-changed + (when-let* ((nextf (next-single-property-change (point) 'field))) + (delete-region nextf (1- (point-max))) + t)) + (erc-fill) + ;; Remove trailing whitespace from last line, if any. + (goto-char (point-max)) + (forward-line -1) + (when (re-search-forward "\\s-$" (line-end-position) t) + (delete-region (match-beginning 0) (match-end 0))) + ;; Neuter timestamp caching to force insertion. + (when (or left-changed right-changed) + (when left-changed + (setq erc-timestamp-last-inserted-left nil)) + (when right-changed + (setq erc-timestamp-last-inserted-right nil)) + t))) =20 (defun erc-fill--hack-csf (f) ;; HACK until necessary additions to erc-stamp.el arrive (possibly @@ -162,7 +179,7 @@ erc-fill--refill (inhibit-read-only t) (inhibit-point-motion-hooks t) ;; - left-changed right-changed ct) ; cached current time + ct) ; cached current time (cl-letf (((symbol-function #'erc-restore-text-properties) #'ignore) ((symbol-function #'current-time) (lambda () ct))) (while @@ -188,19 +205,8 @@ erc-fill--refill (end (text-property-not-all beg (point-max) 'cursor-sensor-functions val)= )) (save-restriction - (narrow-to-region beg end) - (setq left-changed (erc-fill--remove-stamp-left)) - ;; If NOSQUEEZE seems warranted, see note above. - (let ((fill-column (- (point-max) (point-min)))) - (fill-region (point-min) (point-max))) - (setq right-changed (erc-fill--remove-stamp-right)) - (erc-fill) - (when (setq ct (when (or left-changed right-changed) - (erc-fill--hack-csf (car val)))) - (when left-changed - (setq erc-timestamp-last-inserted-left nil)) - (when right-changed - (setq erc-timestamp-last-inserted-right nil)) + (when (setq ct (and (erc-fill--refill-message beg end) + (erc-fill--hack-csf (car val)))) (erc-add-timestamp)) (when reporter (cl-incf (aref (cdr reporter) 2) ; max +=3D d_new - d_old diff --git a/test/lisp/erc/erc-fill-resources/static-60.buffer b/test/lisp/= erc/erc-fill-resources/static-60.buffer index b33f11ae96..f8db4bf7f4 100644 --- a/test/lisp/erc/erc-fill-resources/static-60.buffer +++ b/test/lisp/erc/erc-fill-resources/static-60.buffer @@ -2,7 +2,9 @@ =20 =20 [Tue Jan 1 1980] - *** #chan modes: +nt [00:00] + *** Users on #chan: alice @bob robot + tester [00:00] + *** #chan modes: +nt *** #chan was created on 2021-05-04 05:06:19 lorem ipsum This buffer is for @@ -10,9 +12,10 @@ Lisp evaluation. [00:01] tester, welcome! Your name may or may not be highlighted depending - on whether button's been loaded - by an earlier test. ERC needs - help! [00:03] + on whether erc-button's been + enabled by an earlier test. ERC + needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82= =E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\_o< QUACK! =20 [Wed Jan 2 1980] tester, welcome! To create a diff --git a/test/lisp/erc/erc-fill-resources/static-72.buffer b/test/lisp/= erc/erc-fill-resources/static-72.buffer index 79ed88d112..6523f0887e 100644 --- a/test/lisp/erc/erc-fill-resources/static-72.buffer +++ b/test/lisp/erc/erc-fill-resources/static-72.buffer @@ -2,14 +2,17 @@ =20 =20 [Tue Jan 1 1980] - *** #chan modes: +nt [00:00] + *** Users on #chan: alice @bob robot tester + [00:00] + *** #chan modes: +nt *** #chan was created on 2021-05-04 05:06:19 lorem ipsum This buffer is for text that is not saved, and for Lisp evaluation. [00:01] tester, welcome! Your name may or may not be - highlighted depending on whether button's - been loaded by an earlier test. ERC needs + highlighted depending on whether erc-button's + been enabled by an earlier test. ERC needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82= =E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\_o< QUACK! =20 [Wed Jan 2 1980] tester, welcome! To create a file, visit it diff --git a/test/lisp/erc/erc-fill-resources/variable-60.buffer b/test/lis= p/erc/erc-fill-resources/variable-60.buffer index 4bf2741af0..38723209bf 100644 --- a/test/lisp/erc/erc-fill-resources/variable-60.buffer +++ b/test/lisp/erc/erc-fill-resources/variable-60.buffer @@ -2,13 +2,15 @@ =20 =20 [Tue Jan 1 1980] -*** #chan modes: +nt [00:00] +*** Users on #chan: alice @bob robot tester [00:00] +*** #chan modes: +nt *** #chan was created on 2021-05-04 05:06:19 lorem ipsum This buffer is for text that is not saved, and for Lisp evaluation. [00:01] tester, welcome! Your name may or may not be - highlighted depending on whether button's been - loaded by an earlier test. ERC needs help! [00:03] + highlighted depending on whether erc-button's been + enabled by an earlier test. ERC needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3= =82=9C=E3=82=9C\_o< QUACK! =20 [Wed Jan 2 1980] tester, welcome! To create a file, visit it with ? and diff --git a/test/lisp/erc/erc-fill-resources/variable-72.buffer b/test/lis= p/erc/erc-fill-resources/variable-72.buffer index de376cc15d..cc2410d7a7 100644 --- a/test/lisp/erc/erc-fill-resources/variable-72.buffer +++ b/test/lisp/erc/erc-fill-resources/variable-72.buffer @@ -2,13 +2,15 @@ =20 =20 [Tue Jan 1 1980] -*** #chan modes: +nt [00:00] +*** Users on #chan: alice @bob robot tester [00:00] +*** #chan modes: +nt *** #chan was created on 2021-05-04 05:06:19 lorem ipsum This buffer is for text that is not saved, and for Lisp evaluation. [00:01] tester, welcome! Your name may or may not be highlighted - depending on whether button's been loaded by an earlier + depending on whether erc-button's been enabled by an earlier test. ERC needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3= =82=9C=E3=82=9C\_o< QUACK! =20 [Wed Jan 2 1980] tester, welcome! To create a file, visit it with ? and enter text diff --git a/test/lisp/erc/erc-fill-tests.el b/test/lisp/erc/erc-fill-tests= .el index a7e3d78d74..a0b695a6c7 100644 --- a/test/lisp/erc/erc-fill-tests.el +++ b/test/lisp/erc/erc-fill-tests.el @@ -67,6 +67,10 @@ erc-fill-tests--populate =20 (cl-letf (((symbol-function 'current-time) (lambda () ct))) (with-current-buffer "foonet" + (erc-fill-tests--insert ":irc.foonet.org 353 tester =3D #chan :" + "alice @bob robot tester") + (erc-fill-tests--insert ":irc.foonet.org 366 tester #chan :" + "End of /NAMES list.") (erc-fill-tests--insert ":irc.foonet.org 324 tester #chan +nt") (erc-fill-tests--insert ":irc.foonet.org 329 tester #chan 16201047= 79") =20 @@ -79,7 +83,10 @@ erc-fill-tests--populate (erc-fill-tests--insert ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!" " Your name may or may not be highlighted depending on whether" - " button's been loaded by an earlier test. ERC needs help!") + " erc-button's been enabled by an earlier test. ERC needs help!") + + (erc-fill-tests--insert + ":robot!~u@rz2v467q4rwhy.irc PRIVMSG #chan :=E3=83=BB=E3=82=9C=E3= =82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\\_o< QUACK!") =20 (setq ct (time-convert (cl-incf ts (* 60 60 24)))) (erc-fill-tests--insert @@ -87,14 +94,6 @@ erc-fill-tests--populate " To create a file, visit it with ? and enter text in its buffer.= "))))) =20 (defun erc-fill-tests--teardown () - ;; XXX when inspecting manually, must reactivate fill and stamp modes. - ;; Otherwise `erc-fill-buffer' won't work. - (dolist (buf '("variable-60.buffer" - "variable-72.buffer" - "static-60.buffer" - "static-72.buffer")) - (when (buffer-live-p buf) - (kill-buffer buf))) (advice-remove 'format-time-string 'ts) (let (erc-kill-server-hook erc-kill-channel-hook) @@ -106,7 +105,8 @@ erc-fill-tests--compare ;; Git didn't allow committing with a trailing space after the ;; prompt, hence this: (equal (substring-no-properties (buffer-string) 0 -1) - (with-current-buffer (find-file-literally (ert-resource-file name= )) + (with-temp-buffer + (insert-file-contents (ert-resource-file name)) (buffer-string)))) =20 (defun erc-fill-tests--await-fill () --=20 2.31.1 --=-=-= Content-Type: text/x-patch; charset=utf-8 Content-Disposition: attachment; filename=0001-Add-command-to-refill-ERC-buffers.patch Content-Transfer-Encoding: quoted-printable >From 1058b9202f9b530062bd5268c81a111976db61f2 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 16 Nov 2021 06:28:25 -0800 Subject: [PATCH 1/1] Add command to refill ERC buffers * lisp/erc/erc-fill.el (erc-fill-buffer, erc-fill--refill, erc-fill--refill-thread, erc-fill--refill-message, erc-fill--hack-csf): Add new command and helpers to refill ERC buffers. * lisp/erc/erc-fill-tests.el: Add new file containing tests for `erc-fill-buffer'. Add some support files to test against in lisp/erc/erc-fill-resources. --- lisp/erc/erc-fill.el | 121 ++++++++++ .../erc/erc-fill-resources/static-60.buffer | 24 ++ .../erc/erc-fill-resources/static-72.buffer | 20 ++ .../erc/erc-fill-resources/variable-60.buffer | 18 ++ .../erc/erc-fill-resources/variable-72.buffer | 18 ++ test/lisp/erc/erc-fill-tests.el | 206 ++++++++++++++++++ 6 files changed, 407 insertions(+) create mode 100644 test/lisp/erc/erc-fill-resources/static-60.buffer create mode 100644 test/lisp/erc/erc-fill-resources/static-72.buffer create mode 100644 test/lisp/erc/erc-fill-resources/variable-60.buffer create mode 100644 test/lisp/erc/erc-fill-resources/variable-72.buffer create mode 100644 test/lisp/erc/erc-fill-tests.el diff --git a/lisp/erc/erc-fill.el b/lisp/erc/erc-fill.el index 9f29b9dad9..49130b9ffc 100644 --- a/lisp/erc/erc-fill.el +++ b/lisp/erc/erc-fill.el @@ -112,6 +112,127 @@ erc-fill-column "The column at which a filled paragraph is broken." :type 'integer) =20 +(defun erc-fill--refill-message (beg end) + "Refill but don't re-stamp region between BEG and END. +Return non-nil if timestamps were removed." + (let (left-changed right-changed) + (narrow-to-region beg end) + ;; Remove at most one left timestamp, if any. + (goto-char (point-min)) + (setq left-changed + ;; FIXME it may be a mistake to blow past leading whitespace + ;; without removing any intervening ws-only field intervals + (when-let* ((beg (save-excursion (skip-syntax-forward ">-") (poi= nt))) + (nextf (when (eq 'erc-timestamp (field-at-pos beg)) + (field-beginning beg t))) + ((eq 'erc-timestamp (get-text-property nextf 'field)= ))) + (goto-char (field-end nextf t)) + (skip-syntax-forward "-") + (delete-region nextf (point)) + t)) + ;; Get everything on one line (if NOSQUEEZE seems warranted, see + ;; note below re ASCII art). + (let ((fill-column (string-width (buffer-string)))) + (fill-region (point-min) (point-max))) + ;; Remove any stamps from right-hand side. + (goto-char (point-min)) + (setq right-changed + (when-let* ((nextf (next-single-property-change (point) 'field))) + (delete-region nextf (1- (point-max))) + t)) + (erc-fill) + ;; Remove trailing whitespace from last line, if any. + (goto-char (point-max)) + (forward-line -1) + (when (re-search-forward "\\s-$" (line-end-position) t) + (delete-region (match-beginning 0) (match-end 0))) + ;; Neuter timestamp caching to force insertion. + (when (or left-changed right-changed) + (when left-changed + (setq erc-timestamp-last-inserted-left nil)) + (when right-changed + (setq erc-timestamp-last-inserted-right nil)) + t))) + +(defun erc-fill--hack-csf (f) + ;; HACK until necessary additions to erc-stamp.el arrive (possibly + ;; with erc-v3 in #49860), there's no civilized way of detecting the + ;; bounds of a displayed message after initial insertion. + ;; + ;; These callback closures are used for that purpose, but they also + ;; contain the timestamp we need. An unforeseen benefit of this + ;; awkwardness is that it plays well with `text-property-not-all', + ;; which needs unique values to match against. That wouldn't be the + ;; case were we to use lisp time objects instead because successive + ;; messages might contain the exact same one. + (if (byte-code-function-p f) (aref (aref f 2) 0) (alist-get 'ct (cadr f)= ))) + +;; Enabling `erc-fill-mode' is ultimately destructive to preformatted +;; text (like ASCII art and figlets), which degenerate immediately +;; upon display. This is permanent because we don't store original +;; messages (though with IRCv3, it may be possible to request a +;; replacement from the server). +(defun erc-fill--refill () + (let ((m (make-marker)) + (reporter (unless noninteractive + (make-progress-reporter "filling" 0 (point-max)))) + (inhibit-read-only t) + (inhibit-point-motion-hooks t) + ;; + ct) ; cached current time + (cl-letf (((symbol-function #'erc-restore-text-properties) #'ignore) + ((symbol-function #'current-time) (lambda () ct))) + (while + (save-excursion + (goto-char (or (marker-position m) (set-marker m (point-min)))) + (when-let* + ((beg (if (get-text-property (point) 'cursor-sensor-functi= ons) + (point) + (when-let* + ((max (min (point-max) (+ 512 (point)))) + (res (next-single-property-change + (point) 'cursor-sensor-functions nil ma= x)) + ((/=3D res max))) ; otherwise, we're done. + res))) + (val (get-text-property beg 'cursor-sensor-functions)) + (beg (progn ; remove left padding, if any. + (goto-char beg) + (skip-syntax-forward "-") + (delete-region (min (line-beginning-position) beg) + (point)) + (point))) + ;; Don't expect output limited to IRC message length. + (end (text-property-not-all beg (point-max) + 'cursor-sensor-functions val)= )) + (save-restriction + (when (setq ct (and (erc-fill--refill-message beg end) + (erc-fill--hack-csf (car val)))) + (erc-add-timestamp)) + (when reporter + (cl-incf (aref (cdr reporter) 2) ; max +=3D d_new - d_old + (- (point-max) (point-min) end (- beg)))) + (set-marker m (goto-char (point-max)))))) + (when reporter + (progress-reporter-update reporter (point))) + (thread-yield))))) + +(defvar-local erc-fill--refill-thread nil + "A thread running a buffer-refill job.") + +(define-error 'erc-fill-canceled "ERC refill canceled" 'error) + +(defun erc-fill-buffer (force) + "Refill an ERC buffer. +With FORCE, cancel an active refill job if one exists." + (interactive "P") + (when (and erc-fill--refill-thread + (thread-live-p erc-fill--refill-thread)) + (if force + (thread-signal erc-fill--refill-thread + 'erc-fill-canceled (list (buffer-name))) + (user-error "Already refilling."))) + (setq erc-fill--refill-thread (make-thread #'erc-fill--refill "erc-fill"= ))) + ;;;###autoload (defun erc-fill () "Fill a region using the function referenced in `erc-fill-function'. diff --git a/test/lisp/erc/erc-fill-resources/static-60.buffer b/test/lisp/= erc/erc-fill-resources/static-60.buffer new file mode 100644 index 0000000000..f8db4bf7f4 --- /dev/null +++ b/test/lisp/erc/erc-fill-resources/static-60.buffer @@ -0,0 +1,24 @@ + + + +[Tue Jan 1 1980] + *** Users on #chan: alice @bob robot + tester [00:00] + *** #chan modes: +nt + *** #chan was created on 2021-05-04 + 05:06:19 + lorem ipsum This buffer is for + text that is not saved, and for + Lisp evaluation. [00:01] + tester, welcome! Your name may or + may not be highlighted depending + on whether erc-button's been + enabled by an earlier test. ERC + needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82= =E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\_o< QUACK! + +[Wed Jan 2 1980] + tester, welcome! To create a + file, visit it with ? and enter + text in its buffer. +ERC> \ No newline at end of file diff --git a/test/lisp/erc/erc-fill-resources/static-72.buffer b/test/lisp/= erc/erc-fill-resources/static-72.buffer new file mode 100644 index 0000000000..6523f0887e --- /dev/null +++ b/test/lisp/erc/erc-fill-resources/static-72.buffer @@ -0,0 +1,20 @@ + + + +[Tue Jan 1 1980] + *** Users on #chan: alice @bob robot tester + [00:00] + *** #chan modes: +nt + *** #chan was created on 2021-05-04 05:06:19 + lorem ipsum This buffer is for text that is + not saved, and for Lisp evaluation. [00:01] + tester, welcome! Your name may or may not be + highlighted depending on whether erc-button's + been enabled by an earlier test. ERC needs + help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82= =E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\_o< QUACK! + +[Wed Jan 2 1980] + tester, welcome! To create a file, visit it + with ? and enter text in its buffer. +ERC> \ No newline at end of file diff --git a/test/lisp/erc/erc-fill-resources/variable-60.buffer b/test/lis= p/erc/erc-fill-resources/variable-60.buffer new file mode 100644 index 0000000000..38723209bf --- /dev/null +++ b/test/lisp/erc/erc-fill-resources/variable-60.buffer @@ -0,0 +1,18 @@ + + + +[Tue Jan 1 1980] +*** Users on #chan: alice @bob robot tester [00:00] +*** #chan modes: +nt +*** #chan was created on 2021-05-04 05:06:19 + lorem ipsum This buffer is for text that is not saved, + and for Lisp evaluation. [00:01] + tester, welcome! Your name may or may not be + highlighted depending on whether erc-button's been + enabled by an earlier test. ERC needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3= =82=9C=E3=82=9C\_o< QUACK! + +[Wed Jan 2 1980] + tester, welcome! To create a file, visit it with ? and + enter text in its buffer. +ERC> \ No newline at end of file diff --git a/test/lisp/erc/erc-fill-resources/variable-72.buffer b/test/lis= p/erc/erc-fill-resources/variable-72.buffer new file mode 100644 index 0000000000..cc2410d7a7 --- /dev/null +++ b/test/lisp/erc/erc-fill-resources/variable-72.buffer @@ -0,0 +1,18 @@ + + + +[Tue Jan 1 1980] +*** Users on #chan: alice @bob robot tester [00:00] +*** #chan modes: +nt +*** #chan was created on 2021-05-04 05:06:19 + lorem ipsum This buffer is for text that is not saved, and for + Lisp evaluation. [00:01] + tester, welcome! Your name may or may not be highlighted + depending on whether erc-button's been enabled by an earlier + test. ERC needs help! [00:03] + =E3=83=BB=E3=82=9C=E3=82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3= =82=9C=E3=82=9C\_o< QUACK! + +[Wed Jan 2 1980] + tester, welcome! To create a file, visit it with ? and enter text + in its buffer. +ERC> \ No newline at end of file diff --git a/test/lisp/erc/erc-fill-tests.el b/test/lisp/erc/erc-fill-tests= .el new file mode 100644 index 0000000000..a0b695a6c7 --- /dev/null +++ b/test/lisp/erc/erc-fill-tests.el @@ -0,0 +1,206 @@ +;;; erc-fill-tests.el --- ERC message filling -*- lexical-binding: t -*- + +;; Copyright (C) 2020-2021 Free Software Foundation, Inc. + +;; This file is part of GNU Emacs. +;; +;; GNU Emacs is free software: you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published +;; by the Free Software Foundation, either version 3 of the License, +;; or (at your option) any later version. +;; +;; GNU Emacs is distributed in the hope that it will be useful, but +;; WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;; General Public License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GNU Emacs. If not, see . + +;;; Code: + +(require 'ert-x) +(require 'erc-fill) + +(defun erc-fill-tests--insert (&rest strings) + (let ((inhibit-read-only t)) + (erc-parse-server-response erc-server-process (apply #'concat strings)= ))) + +(defun erc-fill-tests--setup-server-buffer () + (with-current-buffer (get-buffer-create "foonet") + (erc-mode) + (setq erc-server-process (start-process "true" (current-buffer) "true") + erc-server-current-nick "tester" + erc-server-users (make-hash-table :test #'equal)) + (set-process-query-on-exit-flag erc-server-process nil))) + +(defun erc-fill-tests--setup-channel-buffer () + (with-current-buffer (get-buffer-create "#chan") + (erc-mode) + (insert "\n\n") + (setq erc-input-marker (make-marker) + ;; Kludge to get around saving display prop + erc-timestamp-use-align-to nil + ;; Kludge to make whitespace compare equal without expanding + indent-tabs-mode nil + erc-insert-marker (make-marker) + erc-default-recipients '("#chan") + erc-channel-users (make-hash-table :test #'equal) + erc-server-process (with-current-buffer "foonet" + erc-server-process)) + (set-marker erc-insert-marker (point-max)) + (erc-display-prompt))) + +(defun erc-fill-tests--setup () + (advice-add 'format-time-string :filter-args + (lambda (args) (list (car args) (cadr args) 0)) '((name . ts= ))) + + (erc-stamp-mode +1) + + (erc-fill-tests--setup-server-buffer) + (erc-fill-tests--setup-channel-buffer) + (erc-fill-tests--populate)) + +(defun erc-fill-tests--populate () + (let* ((ts (+ (* 2 60 60 24) (* 60 60 24 365 10))) ; Jan 1 1980 + (ct (time-convert ts))) + + (cl-letf (((symbol-function 'current-time) (lambda () ct))) + (with-current-buffer "foonet" + (erc-fill-tests--insert ":irc.foonet.org 353 tester =3D #chan :" + "alice @bob robot tester") + (erc-fill-tests--insert ":irc.foonet.org 366 tester #chan :" + "End of /NAMES list.") + (erc-fill-tests--insert ":irc.foonet.org 324 tester #chan +nt") + (erc-fill-tests--insert ":irc.foonet.org 329 tester #chan 16201047= 79") + + (setq ct (time-convert (cl-incf ts 60))) + (erc-fill-tests--insert + ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :lorem ipsum" + " This buffer is for text that is not saved, and for Lisp evaluat= ion.") + + (setq ct (time-convert (cl-incf ts 120))) + (erc-fill-tests--insert + ":alice!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!" + " Your name may or may not be highlighted depending on whether" + " erc-button's been enabled by an earlier test. ERC needs help!") + + (erc-fill-tests--insert + ":robot!~u@rz2v467q4rwhy.irc PRIVMSG #chan :=E3=83=BB=E3=82=9C=E3= =82=9C=E3=83=BB=E3=80=82=E3=80=82=E3=83=BB=E3=82=9C=E3=82=9C\\_o< QUACK!") + + (setq ct (time-convert (cl-incf ts (* 60 60 24)))) + (erc-fill-tests--insert + ":bob!~u@rz2v467q4rwhy.irc PRIVMSG #chan :tester, welcome!" + " To create a file, visit it with ? and enter text in its buffer.= "))))) + +(defun erc-fill-tests--teardown () + (advice-remove 'format-time-string 'ts) + (let (erc-kill-server-hook + erc-kill-channel-hook) + (kill-buffer "#chan") + (kill-buffer "foonet")) + (should (=3D erc-fill-column 78))) + +(defun erc-fill-tests--compare (name) + ;; Git didn't allow committing with a trailing space after the + ;; prompt, hence this: + (equal (substring-no-properties (buffer-string) 0 -1) + (with-temp-buffer + (insert-file-contents (ert-resource-file name)) + (buffer-string)))) + +(defun erc-fill-tests--await-fill () + (call-interactively #'erc-fill-buffer) + ;; This timeout silliness seemed a little more realistic than just: + ;; + ;; (thread-join erc-fill--refill-thread) + ;; + ;; Probably dumb, right?. + (with-timeout (3 (error "Failed")) + (while (thread-live-p erc-fill--refill-thread) + (sleep-for 0.01)))) + +(ert-deftest erc-fill-buffer () + (let* (erc-insert-pre-hook + erc-insert-modify-hook + erc-send-modify-hook + erc-mode-hook + erc-stamp-mode + erc-fill--refill-thread) + + (erc-fill-tests--setup) + + (with-current-buffer "#chan" + ;; These would get clobbered by the new thread if we let-bound + ;; them, and we can't set them globally, so best just fake it: + (setq-local erc-fill-mode t + erc-stamp-mode t + erc-fill-column 60) + (erc-fill-tests--await-fill) + (ert-info ("Baseline") + (should (erc-fill-tests--compare "variable-60.buffer"))) + + (ert-info ("Wider") + (setq erc-fill-column 72) + (erc-fill-tests--await-fill) + (should (erc-fill-tests--compare "variable-72.buffer"))) + + (ert-info ("Fancy") + (setq erc-fill-function #'erc-fill-static) + (erc-fill-tests--await-fill) + (should (erc-fill-tests--compare "static-72.buffer"))) + + (ert-info ("Fancy normal") + (setq erc-fill-column 60) + (erc-fill-tests--await-fill) + (should (erc-fill-tests--compare "static-60.buffer"))) + + (ert-info ("Again!") + (erc-fill-tests--await-fill) + (should (erc-fill-tests--compare "static-60.buffer"))) + + (ert-info ("Back home") + (setq erc-fill-function #'erc-fill-variable) + (erc-fill-tests--await-fill) + (should (erc-fill-tests--compare "variable-60.buffer"))))) + + (when noninteractive + (erc-fill-tests--teardown))) + +(ert-deftest erc-fill-buffer--interrupted () + (let* (erc-insert-pre-hook + erc-insert-modify-hook + erc-send-modify-hook + erc-mode-hook + erc-stamp-mode + erc-fill--refill-thread) + + (erc-fill-tests--setup) + + (with-current-buffer "#chan" + (setq-local erc-fill-mode t ; see note re these in prev test + erc-stamp-mode t + erc-fill-column 60) + (erc-fill-tests--await-fill) + (ert-info ("Baseline") + (should (erc-fill-tests--compare "variable-60.buffer"))) + + (ert-info ("Denied") + (setq erc-fill-column 72) + (call-interactively #'erc-fill-buffer) + (should-error (erc-fill-buffer nil)) + (thread-join erc-fill--refill-thread) + (should (erc-fill-tests--compare "variable-72.buffer"))) + + (ert-info ("Canceled") + (setq erc-fill-column 60) + (call-interactively #'erc-fill-buffer) + (sleep-for (cl-random 0.1)) + (erc-fill-buffer t) + (thread-join erc-fill--refill-thread) + (should (erc-fill-tests--compare "variable-60.buffer"))))) + + (when noninteractive + (erc-fill-tests--teardown))) + +;;; erc-fill-tests.el ends here --=20 2.31.1 --=-=-=--