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#60936: 30.0.50; ERC >5.5: Add erc-fill style based on visual-line-mode Date: Tue, 24 Oct 2023 07:29:16 -0700 Message-ID: <87jzrcccw3.fsf__2222.63910561509$1698157805$gmane$org@neverwas.me> References: <87tu0nao77.fsf@neverwas.me> <87a5te47sz.fsf@neverwas.me> <87pm23yawb.fsf@neverwas.me> <874jj3ok58.fsf@neverwas.me> <87cyxi9hlc.fsf@neverwas.me> <87h6mt87al.fsf@neverwas.me> <8734yak6dr.fsf@neverwas.me> <87o7gxe4wq.fsf@neverwas.me> <877cniaewr.fsf@neverwas.me> <877cncg3ss.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="16316"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: emacs-erc@gnu.org To: 60936@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Tue Oct 24 16:29:57 2023 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 1qvIPs-00042f-Mk for geb-bug-gnu-emacs@m.gmane-mx.org; Tue, 24 Oct 2023 16:29:56 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qvIPX-0003vn-A4; Tue, 24 Oct 2023 10:29:35 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qvIPW-0003vY-9D for bug-gnu-emacs@gnu.org; Tue, 24 Oct 2023 10:29:34 -0400 Original-Received: from debbugs.gnu.org ([2001:470:142:5::43]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qvIPV-00015f-V6 for bug-gnu-emacs@gnu.org; Tue, 24 Oct 2023 10:29:34 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1qvIPz-0007iu-3d for bug-gnu-emacs@gnu.org; Tue, 24 Oct 2023 10:30:03 -0400 X-Loop: help-debbugs@gnu.org Resent-From: "J.P." Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Tue, 24 Oct 2023 14:30:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 60936 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 60936-submit@debbugs.gnu.org id=B60936.169815780029655 (code B ref 60936); Tue, 24 Oct 2023 14:30:03 +0000 Original-Received: (at 60936) by debbugs.gnu.org; 24 Oct 2023 14:30:00 +0000 Original-Received: from localhost ([127.0.0.1]:56104 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qvIPu-0007iA-CA for submit@debbugs.gnu.org; Tue, 24 Oct 2023 10:30:00 -0400 Original-Received: from mail-108-mta172.mxroute.com ([136.175.108.172]:45985) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1qvIPp-0007hz-4w for 60936@debbugs.gnu.org; Tue, 24 Oct 2023 10:29:57 -0400 Original-Received: from filter006.mxroute.com ([136.175.111.2] filter006.mxroute.com) (Authenticated sender: mN4UYu2MZsgR) by mail-108-mta172.mxroute.com (ZoneMTA) with ESMTPSA id 18b621710f10008912.001 for <60936@debbugs.gnu.org> (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Tue, 24 Oct 2023 14:29:20 +0000 X-Zone-Loop: 7646fcb628dfc912cf9e011a75eb67a58a3561e7a37e X-Originating-IP: [136.175.111.2] 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:Date:References:In-Reply-To: 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=moywq4/QX3aN4rS7Mw9uWNMQR4B8iq2pKYmV/AvCoOQ=; b=GERaL+T+6Ayck6GLUFa296F1oF i71jHAzDLrrZNnASUEO3VSndEjuo6X6eanlHhbqT+oD91DVQajQIa+X+XWKfZBADqRCxeMSlRiUoD j1hNRuF3D8mmfsgxPRM9vAlwV8GD0x9Cz0aa6EqysoYGTmYvV5XkzoPoSKOUuAsSJAqa3IuDnRfJH wl31yFVBYR3fhKRFBS+daBmSgOaBR5fpcfkeMrx6IdGelm7kJpvgE7MVnQL4lqYO6uOsRByN0t+so FCuVsR7km4cDjYSZoB33RjtoRLNBk1vyV1E7Baa3XfhXicnz1c0bGanRa7Lk9rB3ZtlLBh5fTLgLn e/alLMGQ==; In-Reply-To: <877cncg3ss.fsf@neverwas.me> (J. P.'s message of "Mon, 23 Oct 2023 19:19:47 -0700") X-Authenticated-Id: masked@neverwas.me 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-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.bugs:273109 Archived-At: --=-=-= Content-Type: text/plain v2. Fix date-stamp regression in erc-track. Optionally reinstate old "prepended" date-stamp behavior gated by new compat var. Earlier changes for this feature introduced a regression involving date stamps and the option `erc-track-exclude-types'. Basically, date stamps aren't supposed to affect the mode line, at least so long as their inciting message's command appears in `erc-track-exclude-types'. However, this changed after c68dc7786fc * Manage some text props for ERC insertion-hook members To reproduce from -Q: 1. Connect and ensure "JOIN" appears in `erc-track-exclude-types' 2. Join #chan 3. From the server buffer, do (with-current-buffer "#chan" (setq erc-timestamp-last-inserted-left nil)) 3. Connect and join #chan from another client 4. Notice a [#c] in the mode line of the original client Thanks to Corwin for pointing this out. The way I'm proposing we tackle this is to decouple date stamps from `erc-track-exclude-types' completely. That is, have erc-track completely ignore them, so they never affect the mode line. In addition to this fix, I've also added a path for accessing the old behavior in which date stamps aren't standalone messages. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0000-v1-v2.diff >From 48dfdc118270fbd72ea93ca02363dcda5d7ef528 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Tue, 24 Oct 2023 07:09:53 -0700 Subject: [PATCH 0/3] *** NOT A PATCH *** *** BLURB HERE *** F. Jason Park (3): ; * lisp/erc/erc.el (erc-after-connect): Remove package-version. [5.6] Ignore date stamps in erc-track [5.6] Ensure marker for max pos in erc--traverse-inserted etc/ERC-NEWS | 10 ++- lisp/erc/erc-stamp.el | 36 +++++++--- lisp/erc/erc-track.el | 14 ++-- lisp/erc/erc.el | 36 ++++++++-- test/lisp/erc/erc-scenarios-stamp.el | 28 +++++++- test/lisp/erc/erc-tests.el | 84 ++++++++++++++++++++++-- test/lisp/erc/resources/erc-d/erc-d-t.el | 1 + 7 files changed, 182 insertions(+), 27 deletions(-) Interdiff: diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 41ab9cc4c5e..f59023eae62 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -228,6 +228,12 @@ with a legitimate use for this option likely also possesses the knowledge to rig up a suitable analog with minimal effort. That said, the road to removal is long. +** The 'track' module always ignores date stamps. +Users of the stamp module who leave 'erc-insert-timestamp-function' +set to its default of 'erc-insert-timestamp-left-and-right' will find +that date stamps no longer affect the mode line, even for IRC commands +not included in 'erc-track-exclude-types'. + ** Option 'erc-warn-about-blank-lines' is more informative. Enabled by default, this option now produces more useful feedback whenever ERC rejects prompt input containing whitespace-only lines. @@ -348,7 +354,9 @@ 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 final trailing newline in 'erc-timestamp-format-left'. If you +must, see variable 'erc-stamp-prepend-date-stamps-p' for a temporary +escape hatch. *** 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-stamp.el b/lisp/erc/erc-stamp.el index 56fa975c32d..6e35c5e2244 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -688,6 +688,16 @@ erc-stamp--lr-date-on-pre-modify (let (erc-timestamp-format erc-away-timestamp-format) (erc-add-timestamp))))) +(defvar erc-stamp-prepend-date-stamps-p nil + "When non-nil, don't treat date stamps as independent messages. +This is an escape hatch. When enabled, expect post-5.5 features, +like `fill-wrap', dynamic invisibility, etc., to malfunction +severely or lead to a degraded experience. Also know that +support for the default configuration, without any customization, +may expire before the next major release.") +(make-obsolete-variable 'erc-stamp-prepend-date-stamps-p + "unsupported legacy behavior" "30.1") + (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, @@ -702,7 +712,7 @@ erc-insert-timestamp-left-and-right 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 + (unless (or erc-stamp--date-format-end erc-stamp-prepend-date-stamps-p) (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)) @@ -718,6 +728,13 @@ erc-insert-timestamp-left-and-right (if erc-timestamp-format-right (erc-format-timestamp ct erc-timestamp-format-right) string)))) + ;; Maybe insert legacy date stamp. + (when-let ((erc-stamp-prepend-date-stamps-p) + (ts-left (erc-format-timestamp ct erc-timestamp-format-left)) + ((not (string= ts-left erc-timestamp-last-inserted-left)))) + (goto-char (point-min)) + (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left) + (insert (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)) diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index c8f2e04c3eb..a36b781e04d 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -785,6 +785,9 @@ erc-track-select-mode-line-face choice)) choice)))) +(defvar erc-track--skipped-msgs '(datestamp) + "Values of `erc-msg' text prop to ignore.") + (defun erc-track-modified-channels () "Hook function for `erc-insert-post-hook'. Check if the current buffer should be added to the mode line as a @@ -798,10 +801,13 @@ erc-track-modified-channels ;; FIXME either use `erc--server-buffer-p' or ;; explain why that's unwise. (erc-server-or-unjoined-channel-buffer-p))) - (not (erc-message-type-member - (or (erc-find-parsed-property) - (point-min)) - erc-track-exclude-types))) + (not (let ((parsed (erc-find-parsed-property))) + (or (erc-message-type-member (or parsed (point-min)) + erc-track-exclude-types) + ;; Skip certain non-server-sent messages. + (and (not parsed) + (erc--check-msg-prop 'erc-msg + erc-track--skipped-msgs)))))) ;; If the active buffer is not visible (not shown in a ;; window), and not to be excluded, determine the kinds of ;; faces used in the current message, and unless the user diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 92f6f1fcb1f..872ce5b4f49 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2490,7 +2490,6 @@ erc-after-connect to the 376/422 message's \"sender\", as well as the current nick, as given by the 376/422 message's \"target\" parameter, which is typically the same as that reported by `erc-current-nick'." - :package-version '(ERC . "5.6") ; FIXME sync on release :group 'erc-hooks :type '(repeat function)) @@ -2981,7 +2980,7 @@ erc--get-inserted-msg-bounds (and-let* ((p (previous-single-property-change point 'erc-msg))) - (if (= p (1- point)) point (1- p))))))) + (if (= p (1- point)) p (1- p))))))) ,@(and (member only '(nil 'end)) '((e (1- (next-single-property-change (if at-start-p (1+ point) point) diff --git a/test/lisp/erc/erc-scenarios-stamp.el b/test/lisp/erc/erc-scenarios-stamp.el index d6b5d868ce5..c420e62fe14 100644 --- a/test/lisp/erc/erc-scenarios-stamp.el +++ b/test/lisp/erc/erc-scenarios-stamp.el @@ -50,7 +50,6 @@ erc-scenarios-stamp--left/display-margin-mode (erc-stamp--current-time 704591940) (erc-stamp--tz t) (erc-server-flood-penalty 0.1) - (erc-timestamp-only-if-changed-flag nil) (erc-insert-timestamp-function #'erc-insert-timestamp-left) (erc-modules (cons 'fill-wrap erc-modules)) (erc-timestamp-only-if-changed-flag nil) @@ -87,4 +86,31 @@ erc-scenarios-stamp--left/display-margin-mode (should (looking-back "CEIMRUabefhiklmnoqstuv\n")) (should (looking-at (rx "["))))))))) +(ert-deftest erc-scenarios-stamp--legacy-date-stamps () + (with-suppressed-warnings ((obsolete erc-stamp-prepend-date-stamps-p)) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/reconnect") + (erc-stamp-prepend-date-stamps-p t) + (dumb-server (erc-d-run "localhost" t 'unexpected-disconnect)) + (port (process-contact dumb-server :service)) + (erc-server-flood-penalty 0.1) + (expect (erc-d-t-make-expecter))) + + (ert-info ("Connect") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :full-name "tester" + :nick "tester") + (funcall expect 5 "opening connection") + (goto-char (1- (match-beginning 0))) + (should (eq 'erc-timestamp (field-at-pos (point)))) + (should (eq 'unknown (erc--get-inserted-msg-prop 'erc-msg))) + ;; Force redraw of date stamp. + (setq erc-timestamp-last-inserted-left nil) + + (funcall expect 5 "This server is in debug mode") + (while (and (zerop (forward-line -1)) + (not (eq 'erc-timestamp (field-at-pos (point)))))) + (should (erc--get-inserted-msg-prop 'erc-cmd))))))) + ;;; erc-scenarios-stamp.el ends here diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 6429fce8861..1af087e7e31 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1481,7 +1481,30 @@ erc--delete-inserted-message (with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p)) (let ((erc-legacy-invisible-bounds-p t)) (erc--delete-inserted-message (point)))) - (should (looking-at (rx "*** four\n"))))) + (should (looking-at (rx "*** four\n")))) + + (ert-info ("Deleting most recent message preserves markers") + (let ((m (point-marker)) + (n (point-marker)) + (p (point))) + (should (equal "*** four\n" (buffer-substring p erc-insert-marker))) + (set-marker-insertion-type m t) + (goto-char (point-max)) + (erc--delete-inserted-message p) + (should (= (marker-position m) p)) + (should (= (marker-position n) p)) + (goto-char p) + (should (looking-back (rx "*** one\n"))) + (should (looking-at erc-prompt)) + (erc--assert-input-bounds) + + ;; However, `m' is now forever "trapped" at `erc-insert-marker'. + (erc-display-message nil 'notice nil "two") + (should (= m erc-insert-marker)) + (goto-char n) + (should (looking-at (rx "*** two\n"))) + (set-marker m nil) + (set-marker n nil)))) (ert-deftest erc--order-text-properties-from-hash () (let ((table (map-into '((a . 1) -- 2.41.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0001-lisp-erc-erc.el-erc-after-connect-Remove-package-ver.patch >From 359cd55879ee0bce87b52547e1d3e3ee087d8108 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Mon, 23 Oct 2023 19:33:32 -0700 Subject: [PATCH 1/3] ; * lisp/erc/erc.el (erc-after-connect): Remove package-version. --- lisp/erc/erc.el | 1 - 1 file changed, 1 deletion(-) diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index 7d75ec49ccd..f618fb17076 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2490,7 +2490,6 @@ erc-after-connect to the 376/422 message's \"sender\", as well as the current nick, as given by the 376/422 message's \"target\" parameter, which is typically the same as that reported by `erc-current-nick'." - :package-version '(ERC . "5.6") ; FIXME sync on release :group 'erc-hooks :type '(repeat function)) -- 2.41.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0002-5.6-Ignore-date-stamps-in-erc-track.patch >From bfe93b485c0760bd7c23f8bf3e8da8c53b68069b Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Mon, 23 Oct 2023 21:59:25 -0700 Subject: [PATCH 2/3] [5.6] Ignore date stamps in erc-track * etc/ERC-NEWS: Mention that date stamps no longer optionally affect the mode line. Also mention but discourage new variable 'erc-stamp-prepend-date-stamps-p'. * lisp/erc/erc-stamp.el (erc-stamp-prepend-date-stamps-p): New variable, an escape hatch to allow date stamps to once again be prepended to messages. (erc-insert-timestamp-left-and-right): Don't insert stamps as independent messages when legacy flag `erc-stamp-prepend-date-stamps-p' is non-nil. * lisp/erc/erc-track.el (erc-track--skipped-msgs): New internal variable. (erc-track-modified-channels): In previous versions, a date stamp accompanying a message for an IRC command appearing in `erc-track-exclude-types' would have no effect on the mode line. That they were able to otherwise was probably a bug. Regardless, this behavior changed after date stamps became independent messages with c68dc7786fc "Manage some text props for ERC insertion-hook members". This commit corrects this regression by making ERC always ignore date stamps. Thanks to Corwin Brust for spotting this. * test/lisp/erc/erc-scenarios-stamp.el (erc-scenarios-stamp--left/display-margin-mode): Remove redundant binding. (erc-scenarios-stamp--legacy-date-stamps): New test. (Bug#60936) --- etc/ERC-NEWS | 10 +++++++++- lisp/erc/erc-stamp.el | 19 ++++++++++++++++++- lisp/erc/erc-track.el | 14 ++++++++++---- test/lisp/erc/erc-scenarios-stamp.el | 28 +++++++++++++++++++++++++++- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/etc/ERC-NEWS b/etc/ERC-NEWS index 41ab9cc4c5e..f59023eae62 100644 --- a/etc/ERC-NEWS +++ b/etc/ERC-NEWS @@ -228,6 +228,12 @@ with a legitimate use for this option likely also possesses the knowledge to rig up a suitable analog with minimal effort. That said, the road to removal is long. +** The 'track' module always ignores date stamps. +Users of the stamp module who leave 'erc-insert-timestamp-function' +set to its default of 'erc-insert-timestamp-left-and-right' will find +that date stamps no longer affect the mode line, even for IRC commands +not included in 'erc-track-exclude-types'. + ** Option 'erc-warn-about-blank-lines' is more informative. Enabled by default, this option now produces more useful feedback whenever ERC rejects prompt input containing whitespace-only lines. @@ -348,7 +354,9 @@ 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 final trailing newline in 'erc-timestamp-format-left'. If you +must, see variable 'erc-stamp-prepend-date-stamps-p' for a temporary +escape hatch. *** 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-stamp.el b/lisp/erc/erc-stamp.el index b515513dcb7..e0db472d289 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -689,6 +689,16 @@ erc-stamp--lr-date-on-pre-modify (let (erc-timestamp-format erc-away-timestamp-format) (erc-add-timestamp))))) +(defvar erc-stamp-prepend-date-stamps-p nil + "When non-nil, don't treat date stamps as independent messages. +This is an escape hatch. When enabled, expect post-5.5 features, +like `fill-wrap', dynamic invisibility, etc., to malfunction +severely or lead to a degraded experience. Also know that +support for the default configuration, without any customization, +may expire before the next major release.") +(make-obsolete-variable 'erc-stamp-prepend-date-stamps-p + "unsupported legacy behavior" "30.1") + (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, @@ -703,7 +713,7 @@ erc-insert-timestamp-left-and-right 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 + (unless (or erc-stamp--date-format-end erc-stamp-prepend-date-stamps-p) (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)) @@ -719,6 +729,13 @@ erc-insert-timestamp-left-and-right (if erc-timestamp-format-right (erc-format-timestamp ct erc-timestamp-format-right) string)))) + ;; Maybe insert legacy date stamp. + (when-let ((erc-stamp-prepend-date-stamps-p) + (ts-left (erc-format-timestamp ct erc-timestamp-format-left)) + ((not (string= ts-left erc-timestamp-last-inserted-left)))) + (goto-char (point-min)) + (erc-put-text-property 0 (length ts-left) 'field 'erc-timestamp ts-left) + (insert (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)) diff --git a/lisp/erc/erc-track.el b/lisp/erc/erc-track.el index c8f2e04c3eb..a36b781e04d 100644 --- a/lisp/erc/erc-track.el +++ b/lisp/erc/erc-track.el @@ -785,6 +785,9 @@ erc-track-select-mode-line-face choice)) choice)))) +(defvar erc-track--skipped-msgs '(datestamp) + "Values of `erc-msg' text prop to ignore.") + (defun erc-track-modified-channels () "Hook function for `erc-insert-post-hook'. Check if the current buffer should be added to the mode line as a @@ -798,10 +801,13 @@ erc-track-modified-channels ;; FIXME either use `erc--server-buffer-p' or ;; explain why that's unwise. (erc-server-or-unjoined-channel-buffer-p))) - (not (erc-message-type-member - (or (erc-find-parsed-property) - (point-min)) - erc-track-exclude-types))) + (not (let ((parsed (erc-find-parsed-property))) + (or (erc-message-type-member (or parsed (point-min)) + erc-track-exclude-types) + ;; Skip certain non-server-sent messages. + (and (not parsed) + (erc--check-msg-prop 'erc-msg + erc-track--skipped-msgs)))))) ;; If the active buffer is not visible (not shown in a ;; window), and not to be excluded, determine the kinds of ;; faces used in the current message, and unless the user diff --git a/test/lisp/erc/erc-scenarios-stamp.el b/test/lisp/erc/erc-scenarios-stamp.el index d6b5d868ce5..c420e62fe14 100644 --- a/test/lisp/erc/erc-scenarios-stamp.el +++ b/test/lisp/erc/erc-scenarios-stamp.el @@ -50,7 +50,6 @@ erc-scenarios-stamp--left/display-margin-mode (erc-stamp--current-time 704591940) (erc-stamp--tz t) (erc-server-flood-penalty 0.1) - (erc-timestamp-only-if-changed-flag nil) (erc-insert-timestamp-function #'erc-insert-timestamp-left) (erc-modules (cons 'fill-wrap erc-modules)) (erc-timestamp-only-if-changed-flag nil) @@ -87,4 +86,31 @@ erc-scenarios-stamp--left/display-margin-mode (should (looking-back "CEIMRUabefhiklmnoqstuv\n")) (should (looking-at (rx "["))))))))) +(ert-deftest erc-scenarios-stamp--legacy-date-stamps () + (with-suppressed-warnings ((obsolete erc-stamp-prepend-date-stamps-p)) + (erc-scenarios-common-with-cleanup + ((erc-scenarios-common-dialog "base/reconnect") + (erc-stamp-prepend-date-stamps-p t) + (dumb-server (erc-d-run "localhost" t 'unexpected-disconnect)) + (port (process-contact dumb-server :service)) + (erc-server-flood-penalty 0.1) + (expect (erc-d-t-make-expecter))) + + (ert-info ("Connect") + (with-current-buffer (erc :server "127.0.0.1" + :port port + :full-name "tester" + :nick "tester") + (funcall expect 5 "opening connection") + (goto-char (1- (match-beginning 0))) + (should (eq 'erc-timestamp (field-at-pos (point)))) + (should (eq 'unknown (erc--get-inserted-msg-prop 'erc-msg))) + ;; Force redraw of date stamp. + (setq erc-timestamp-last-inserted-left nil) + + (funcall expect 5 "This server is in debug mode") + (while (and (zerop (forward-line -1)) + (not (eq 'erc-timestamp (field-at-pos (point)))))) + (should (erc--get-inserted-msg-prop 'erc-cmd))))))) + ;;; erc-scenarios-stamp.el ends here -- 2.41.0 --=-=-= Content-Type: text/x-patch Content-Disposition: attachment; filename=0003-5.6-Ensure-marker-for-max-pos-in-erc-traverse-insert.patch >From 48dfdc118270fbd72ea93ca02363dcda5d7ef528 Mon Sep 17 00:00:00 2001 From: "F. Jason Park" Date: Sat, 21 Oct 2023 13:53:46 -0700 Subject: [PATCH 3/3] [5.6] Ensure marker for max pos in erc--traverse-inserted * lisp/erc/erc-stamp.el (erc-stamp--propertize-left-date-stamp): Run `erc-stamp--insert-date-hook' here. (erc-stamp--insert-date-stamp-as-phony-message): Don't include value of `erc-stamp--insert-date-hook' in let-bound `erc-insert-modify-hook' because it runs twice if buffer-local. Also call getter for `erc-stamp--current-time' and remove `erc-send-modify-hook' because that only runs via `erc-display-msg'. (erc-stamp--lr-date-on-pre-modify, erc-insert-timestamp-left-and-right): Use function form of `erc-stamp--current-time' for determining current time stamp. * lisp/erc/erc.el (erc--get-inserted-msg-bounds): Fix off-by-one. (erc--traverse-inserted): Create temporary marker when END is non-nil and not already a marker so that insertions and deletions do not affect the position at which the loop should end. (erc--delete-inserted-message): New function. * test/lisp/erc/erc-tests.el (erc--delete-inserted-message): New test. (erc--update-modules/unknown): Improve readability slightly. * test/lisp/erc/resources/erc-d/erc-d-t.el (erc-d-t-make-expecter): Indicate assertion flavor in error message. (Bug#60936) --- lisp/erc/erc-stamp.el | 17 +++-- lisp/erc/erc.el | 35 ++++++++-- test/lisp/erc/erc-tests.el | 84 ++++++++++++++++++++++-- test/lisp/erc/resources/erc-d/erc-d-t.el | 1 + 4 files changed, 118 insertions(+), 19 deletions(-) diff --git a/lisp/erc/erc-stamp.el b/lisp/erc/erc-stamp.el index e0db472d289..6e35c5e2244 100644 --- a/lisp/erc/erc-stamp.el +++ b/lisp/erc/erc-stamp.el @@ -638,7 +638,8 @@ erc-stamp--date-format-end (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)) + (erc--hide-message 'timestamp) + (run-hooks 'erc-stamp--insert-date-hook)) ;; A kludge to pass state from insert hook to nested insert hook. (defvar erc-stamp--current-datestamp-left nil) @@ -665,19 +666,17 @@ erc-stamp--insert-date-stamp-as-phony-message (cl-assert string) (let ((erc-stamp--skip t) (erc--msg-props (map-into `((erc-msg . datestamp) - (erc-ts . ,erc-stamp--current-time)) + (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-stamp--propertize-left-date-stamp)) + ;; Don't run hooks that aren't expecting a narrowed buffer. + (erc-insert-done-hook nil)) (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))) + (when-let ((ct (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) @@ -723,7 +722,7 @@ erc-insert-timestamp-left-and-right (narrow-to-region erc--insert-marker end-marker) (set-marker end-marker nil) (set-marker erc--insert-marker nil))) - (let* ((ct (or erc-stamp--current-time (erc-stamp--current-time))) + (let* ((ct (erc-stamp--current-time)) (ts-right (with-suppressed-warnings ((obsolete erc-timestamp-format-right)) (if erc-timestamp-format-right diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el index f618fb17076..872ce5b4f49 100644 --- a/lisp/erc/erc.el +++ b/lisp/erc/erc.el @@ -2980,7 +2980,7 @@ erc--get-inserted-msg-bounds (and-let* ((p (previous-single-property-change point 'erc-msg))) - (if (= p (1- point)) point (1- p))))))) + (if (= p (1- point)) p (1- p))))))) ,@(and (member only '(nil 'end)) '((e (1- (next-single-property-change (if at-start-p (1+ point) point) @@ -3005,8 +3005,12 @@ erc--with-inserted-msg ,@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))) + "Visit messages between BEG and END and run FN in narrowed buffer. +If END is a marker, possibly update its position." + (unless (markerp end) + (setq end (set-marker (make-marker) (or end erc-insert-marker)))) + (unless (eq end erc-insert-marker) + (set-marker end (min erc-insert-marker end))) (save-excursion (goto-char beg) (let ((b (if (get-text-property (point) 'erc-msg) @@ -3018,7 +3022,9 @@ erc--traverse-inserted (save-restriction (narrow-to-region b e) (funcall fn)) - (setq b e))))) + (setq b e)))) + (unless (eq end erc-insert-marker) + (set-marker end nil))) (defvar erc--insert-marker nil "Internal override for `erc-insert-marker'.") @@ -3240,6 +3246,27 @@ erc--hide-message (cl-incf beg)) (erc--merge-prop (1- beg) (1- end) 'invisible value))))) +(defun erc--delete-inserted-message (beg-or-point &optional end) + "Remove message between BEG and END. +Expect BEG and END to match bounds as returned by the macro +`erc--get-inserted-msg-bounds'. Ensure all markers residing at +the start of the deleted message end up at the beginning of the +subsequent message." + (let ((beg beg-or-point)) + (save-restriction + (widen) + (unless end + (setq end (erc--get-inserted-msg-bounds nil beg-or-point) + beg (pop end))) + (with-silent-modifications + (if erc-legacy-invisible-bounds-p + (delete-region beg (1+ end)) + (save-excursion + (goto-char beg) + (insert-before-markers + (substring (delete-and-extract-region (1- (point)) (1+ end)) + -1)))))))) + (defvar erc--ranked-properties '(erc-msg erc-ts erc-cmd)) (defun erc--order-text-properties-from-hash (table) diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el index 57bf5860ac4..1af087e7e31 100644 --- a/test/lisp/erc/erc-tests.el +++ b/test/lisp/erc/erc-tests.el @@ -1432,6 +1432,80 @@ erc-process-input-line (should-not calls)))))) +(ert-deftest erc--delete-inserted-message () + (erc-mode) + (erc--initialize-markers (point) nil) + ;; Put unique invisible properties on the line endings. + (erc-display-message nil 'notice nil "one") + (put-text-property (1- erc-insert-marker) erc-insert-marker 'invisible 'a) + (let ((erc--msg-prop-overrides '((erc-msg . datestamp) (erc-ts . 0)))) + (erc-display-message nil nil nil + (propertize "\n[date]" 'field 'erc-timestamp))) + (put-text-property (1- erc-insert-marker) erc-insert-marker 'invisible 'b) + (erc-display-message nil 'notice nil "two") + + (ert-info ("Date stamp deleted cleanly") + (goto-char 11) + (should (looking-at (rx "\n[date]"))) + (should (eq 'datestamp (get-text-property (point) 'erc-msg))) + (should (eq (point) (field-beginning (1+ (point))))) + + (erc--delete-inserted-message (point)) + + ;; Preceding line ending clobbered, replaced by trailing. + (should (looking-back (rx "*** one\n"))) + (should (looking-at (rx "*** two"))) + (should (eq 'b (get-text-property (1- (point)) 'invisible)))) + + (ert-info ("Markers at pos-bol preserved") + (erc-display-message nil 'notice nil "three") + (should (looking-at (rx "*** two"))) + + (let ((m (point-marker)) + (n (point-marker)) + (p (point))) + (set-marker-insertion-type m t) + (goto-char (point-max)) + (erc--delete-inserted-message p) + (should (= (marker-position n) p)) + (should (= (marker-position m) p)) + (goto-char p) + (set-marker m nil) + (set-marker n nil) + (should (looking-back (rx "*** one\n"))) + (should (looking-at (rx "*** three"))))) + + (ert-info ("Compat") + (erc-display-message nil 'notice nil "four") + (should (looking-at (rx "*** three\n"))) + (with-suppressed-warnings ((obsolete erc-legacy-invisible-bounds-p)) + (let ((erc-legacy-invisible-bounds-p t)) + (erc--delete-inserted-message (point)))) + (should (looking-at (rx "*** four\n")))) + + (ert-info ("Deleting most recent message preserves markers") + (let ((m (point-marker)) + (n (point-marker)) + (p (point))) + (should (equal "*** four\n" (buffer-substring p erc-insert-marker))) + (set-marker-insertion-type m t) + (goto-char (point-max)) + (erc--delete-inserted-message p) + (should (= (marker-position m) p)) + (should (= (marker-position n) p)) + (goto-char p) + (should (looking-back (rx "*** one\n"))) + (should (looking-at erc-prompt)) + (erc--assert-input-bounds) + + ;; However, `m' is now forever "trapped" at `erc-insert-marker'. + (erc-display-message nil 'notice nil "two") + (should (= m erc-insert-marker)) + (goto-char n) + (should (looking-at (rx "*** two\n"))) + (set-marker m nil) + (set-marker n nil)))) + (ert-deftest erc--order-text-properties-from-hash () (let ((table (map-into '((a . 1) (erc-ts . 0) @@ -2617,8 +2691,8 @@ erc--update-modules/unknown (obarray (obarray-make)) (err (should-error (erc--update-modules erc-modules)))) (should (equal (cadr err) "`foo' is not a known ERC module")) - (should (equal (funcall get-calls) - `((req . ,(intern-soft "erc-foo"))))))) + (should (equal (mapcar #'prin1-to-string (funcall get-calls)) + '("(req . erc-foo)"))))) ;; Module's mode command exists but lacks an associated file. (ert-info ("Bad autoload flagged as suspect") @@ -2627,10 +2701,8 @@ erc--update-modules/unknown (obarray (obarray-make)) (erc-modules (list (intern "foo")))) - ;; Create a mode activation command. + ;; Create a mode-activation command and make mode-var global. (funcall mk-cmd "foo") - - ;; Make the mode var global. (funcall mk-global "foo") ;; No local modules to return. @@ -2639,7 +2711,7 @@ erc--update-modules/unknown '("foo"))) ;; ERC requires the library via prefixed module name. (should (equal (mapcar #'prin1-to-string (funcall get-calls)) - `("(req . erc-foo)" "(erc-foo-mode . 1)")))))))) + '("(req . erc-foo)" "(erc-foo-mode . 1)")))))))) ;; A local module (here, `lo2') lacks a mode toggle, so ERC tries to ;; load its defining library, first via the symbol property diff --git a/test/lisp/erc/resources/erc-d/erc-d-t.el b/test/lisp/erc/resources/erc-d/erc-d-t.el index cf869fb3c70..7126165fd91 100644 --- a/test/lisp/erc/resources/erc-d/erc-d-t.el +++ b/test/lisp/erc/resources/erc-d/erc-d-t.el @@ -157,6 +157,7 @@ erc-d-t-make-expecter (let (positions) (lambda (timeout text &optional reset-from) (let* ((pos (cdr (assq (current-buffer) positions))) + (erc-d-t--wait-message-prefix (and (< timeout 0) "Sustaining: ")) (cb (lambda () (unless pos (push (cons (current-buffer) (setq pos (make-marker))) -- 2.41.0 --=-=-=--