mirror of
git://git.sv.gnu.org/emacs.git
synced 2026-01-06 03:40:56 -08:00
Account for leading timestamps in erc-match
* lisp/erc/erc-match.el (erc-text-matched-hook): Mention that stamps
may be present in the narrowed buffer but absent from the message
parameter.
(erc-match--message): New function containing what was the body of
`erc-match-message' as if the latter were simply renamed.
(erc-match-message): Move body to `erc-match--message' and call it
with more aggressive narrowing. This fixes a regression stemming from
d880a08f "Cement ordering of essential hook members in ERC". Special
thanks to Libera.Chat user jrm for reporting this bug. (Bug#60936)
* test/lisp/erc/erc-scenarios-match.el: New test file.
This commit is contained in:
parent
d42b45dcc7
commit
99d74dcd45
2 changed files with 149 additions and 12 deletions
|
|
@ -233,10 +233,14 @@ for beeping to work."
|
|||
(const :tag "Don't beep" nil)))
|
||||
|
||||
(defcustom erc-text-matched-hook '(erc-log-matches)
|
||||
"Hook run when text matches a given match-type.
|
||||
Functions in this hook are passed as arguments:
|
||||
\(match-type nick!user@host message) where MATCH-TYPE is a symbol of:
|
||||
current-nick, keyword, pal, dangerous-host, fool."
|
||||
"Abnormal hook for visiting text matching a predefined \"type\".
|
||||
ERC calls members with the arguments (MATCH-TYPE NUH MESSAGE),
|
||||
where MATCH-TYPE is one of the symbols `current-nick', `keyword',
|
||||
`pal', `dangerous-host', `fool', and NUH is an `erc-response'
|
||||
sender, like bob!~bob@example.org. Users should keep in mind
|
||||
that MESSAGE may not include decorations, such as white space or
|
||||
time stamps, preceding the same text as inserted in the narrowed
|
||||
buffer."
|
||||
:options '(erc-log-matches erc-hide-fools erc-beep-on-match)
|
||||
:type 'hook)
|
||||
|
||||
|
|
@ -458,8 +462,19 @@ In any of the following situations, MSG is directed at an entry FOOL:
|
|||
(erc-list-match fools-end msg))))
|
||||
|
||||
(defun erc-match-message ()
|
||||
"Mark certain keywords in a region.
|
||||
Use this defun with `erc-insert-modify-hook'."
|
||||
"Add faces to matching text in inserted message."
|
||||
;; Exclude leading whitespace, stamps, etc.
|
||||
(let ((omin (point-min))
|
||||
(beg (or (and (not (get-text-property (point-min) 'erc-command))
|
||||
(next-single-property-change (point-min) 'erc-command))
|
||||
(point-min))))
|
||||
;; FIXME when ERC no longer supports 28, use `with-restriction'
|
||||
;; with `:label' here instead of passing `omin'.
|
||||
(save-restriction
|
||||
(narrow-to-region beg (point-max))
|
||||
(erc-match--message omin))))
|
||||
|
||||
(defun erc-match--message (unrestricted-point-min)
|
||||
;; This needs some refactoring.
|
||||
(goto-char (point-min))
|
||||
(let* ((to-match-nick-dep '("pal" "fool" "dangerous-host"))
|
||||
|
|
@ -561,12 +576,14 @@ Use this defun with `erc-insert-modify-hook'."
|
|||
'font-lock-face match-face)))
|
||||
;; Else twiddle your thumbs.
|
||||
(t nil))
|
||||
;; FIXME use `without-restriction' after dropping 28.
|
||||
(save-restriction
|
||||
(narrow-to-region unrestricted-point-min (point-max))
|
||||
(run-hook-with-args
|
||||
'erc-text-matched-hook
|
||||
(intern match-type)
|
||||
'erc-text-matched-hook (intern match-type)
|
||||
(or nickuserhost
|
||||
(concat "Server:" (erc-get-parsed-vector-type vector)))
|
||||
message))))
|
||||
message)))))
|
||||
(if nickuserhost
|
||||
(append to-match-nick-dep to-match-nick-indep)
|
||||
to-match-nick-indep)))))
|
||||
|
|
|
|||
120
test/lisp/erc/erc-scenarios-match.el
Normal file
120
test/lisp/erc/erc-scenarios-match.el
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
;;; erc-scenarios-match.el --- Misc `erc-match' scenarios -*- lexical-binding: t -*-
|
||||
|
||||
;; Copyright (C) 2023 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 <https://www.gnu.org/licenses/>.
|
||||
|
||||
;;; Code:
|
||||
|
||||
(require 'ert-x)
|
||||
(eval-and-compile
|
||||
(let ((load-path (cons (ert-resource-directory) load-path)))
|
||||
(require 'erc-scenarios-common)))
|
||||
|
||||
(require 'erc-stamp)
|
||||
(require 'erc-match)
|
||||
|
||||
;; This defends against a regression in which all matching by the
|
||||
;; `erc-match-message' fails when `erc-add-timestamp' precedes it in
|
||||
;; `erc-insert-modify-hook'. Basically, `erc-match-message' used to
|
||||
;; expect an `erc-parsed' text property on the first character in a
|
||||
;; message, which doesn't exist, when the message content is prefixed
|
||||
;; by a leading timestamp.
|
||||
|
||||
(ert-deftest erc-scenarios-match--stamp-left-current-nick ()
|
||||
:tags '(:expensive-test)
|
||||
(erc-scenarios-common-with-cleanup
|
||||
((erc-scenarios-common-dialog "base/reconnect")
|
||||
(dumb-server (erc-d-run "localhost" t 'unexpected-disconnect))
|
||||
(port (process-contact dumb-server :service))
|
||||
(erc-server-flood-penalty 0.1)
|
||||
(erc-insert-timestamp-function 'erc-insert-timestamp-left)
|
||||
(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")
|
||||
(should (memq 'erc-match-message
|
||||
(memq 'erc-add-timestamp erc-insert-modify-hook)))
|
||||
;; The "match type" is `current-nick'.
|
||||
(funcall expect 5 "tester")
|
||||
(should (eq (get-text-property (1- (point)) 'font-lock-face)
|
||||
'erc-current-nick-face))))))
|
||||
|
||||
;; This asserts that when stamps appear before a message,
|
||||
;; some non-nil invisibility property spans the entire message.
|
||||
(ert-deftest erc-scenarios-match--stamp-left-fools-invisible ()
|
||||
:tags '(:expensive-test)
|
||||
(erc-scenarios-common-with-cleanup
|
||||
((erc-scenarios-common-dialog "join/legacy")
|
||||
(dumb-server (erc-d-run "localhost" t 'foonet))
|
||||
(port (process-contact dumb-server :service))
|
||||
(erc-server-flood-penalty 0.1)
|
||||
(erc-insert-timestamp-function 'erc-insert-timestamp-left)
|
||||
(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))
|
||||
(hiddenp (lambda ()
|
||||
(and (eq (field-at-pos (pos-bol)) 'erc-timestamp)
|
||||
(get-text-property (pos-bol) 'invisible)
|
||||
(>= (next-single-property-change (pos-bol)
|
||||
'invisible nil)
|
||||
(pos-eol))))))
|
||||
|
||||
(ert-info ("Connect")
|
||||
(with-current-buffer (erc :server "127.0.0.1"
|
||||
:port port
|
||||
:full-name "tester"
|
||||
:password "changeme"
|
||||
:nick "tester")
|
||||
(should (memq 'erc-match-message
|
||||
(memq 'erc-add-timestamp 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 "<bob> tester, welcome!"))
|
||||
(should (funcall hiddenp))
|
||||
|
||||
;; Alice's is the only one visible.
|
||||
(should (funcall expect 10 "<alice> tester, welcome!"))
|
||||
(should (eq (field-at-pos (pos-bol)) 'erc-timestamp))
|
||||
(should (get-text-property (pos-bol) 'invisible))
|
||||
(should-not (get-text-property (point) 'invisible))
|
||||
|
||||
(should (funcall expect 10 "<bob> alice: But, as it seems"))
|
||||
(should (funcall hiddenp))
|
||||
|
||||
(should (funcall expect 10 "<alice> bob: Well, this is the forest"))
|
||||
(should (funcall hiddenp))
|
||||
|
||||
(should (funcall expect 10 "<alice> bob: And will you"))
|
||||
(should (funcall hiddenp))
|
||||
|
||||
(should (funcall expect 10 "<bob> alice: Live, and be prosperous"))
|
||||
(should (funcall hiddenp))
|
||||
|
||||
(should (funcall expect 10 "ERC>"))
|
||||
(should-not (get-text-property (pos-bol) 'invisible))
|
||||
(should-not (get-text-property (point) 'invisible))))))
|
||||
|
||||
(eval-when-compile (require 'erc-join))
|
||||
|
||||
;;; erc-scenarios-match.el ends here
|
||||
Loading…
Add table
Add a link
Reference in a new issue