* 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
@ 2024-03-06 19:26 Fadi Moukayed
2024-03-07 20:29 ` bug#69597: " J.P.
[not found] ` <87v85xn5uv.fsf@neverwas.me>
0 siblings, 2 replies; 10+ messages in thread
From: Fadi Moukayed @ 2024-03-06 19:26 UTC (permalink / raw)
To: bug-gnu-emacs; +Cc: emacs-erc
[-- Attachment #1: Type: text/plain, Size: 7090 bytes --]
Tags: patch
Severity: wishlist
Hi all,
I am submitting a trivial patch adding a simple customizable variable
(erc-format-spoilers) to Erc, allowing the user to control how Erc
displays spoiler text when mIRC formatting code interpretation is
enabled.
This idea for this patch was discussed with the Erc maintainers on
#erc, and was deemed to be useful enough to warrant a submission.
Note that this is my first attempt to contribute to GNU Emacs.
In GNU Emacs 29.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.20,
cairo version 1.16.0) of 2024-02-27 built on lcy02-amd64-095
Repository revision: ac89b1141a261b40ab5607f8d74209ede4c164cc
Repository branch: master
Windowing system distributor 'The X.Org Foundation', version 11.0.12201001
System Description: Ubuntu 22.04.4 LTS
Configured using:
'configure --prefix=/snap/emacs/current/usr --with-x-toolkit=gtk3
--without-xaw3d --with-modules --with-cairo
--with-native-compilation=aot --without-pgtk --with-xinput2
--with-tree-sitter --with-json
'CFLAGS=-isystem/build/emacs/parts/emacs/install/usr/include
-isystem/build/emacs/parts/emacs/install/usr/include/x86_64-linux-gnu
-isystem/build/emacs/stage/usr/include -O2'
'CPPFLAGS=-isystem/build/emacs/parts/emacs/install/usr/include
-isystem/build/emacs/parts/emacs/install/usr/include/x86_64-linux-gnu
-isystem/build/emacs/stage/usr/include'
'LDFLAGS=-L/build/emacs/parts/emacs/install/lib
-L/build/emacs/parts/emacs/install/usr/lib
-L/build/emacs/parts/emacs/install/lib/x86_64-linux-gnu
-L/build/emacs/parts/emacs/install/usr/lib/x86_64-linux-gnu
-L/build/emacs/stage/usr/lib''
Configured features:
ACL CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GPM GSETTINGS HARFBUZZ JPEG
JSON LCMS2 LIBOTF LIBSELINUX LIBSYSTEMD LIBXML2 M17N_FLT MODULES
NATIVE_COMP NOTIFY INOTIFY PDUMPER PNG RSVG SECCOMP SOUND SQLITE3
THREADS TIFF TOOLKIT_SCROLL_BARS TREE_SITTER X11 XDBE XIM XINPUT2 XPM
GTK3 ZLIB
Important settings:
value of $LANG: de_DE.UTF-8
value of $XMODIFIERS: @im=ibus
locale-coding-system: utf-8-unix
Major mode: ERC
Minor modes in effect:
erc-ring-mode: t
erc-notifications-mode: t
erc-nicks-mode: t
erc-netsplit-mode: t
erc-menu-mode: t
erc-list-mode: t
erc-irccontrols-mode: t
erc-keep-place-mode: t
erc-move-to-prompt-mode: t
erc-readonly-mode: t
erc-scrolltobottom-mode: t
erc-imenu-mode: t
erc-pcomplete-mode: t
erc-button--phantom-users-mode: t
erc-button-mode: t
erc-fill-wrap-mode: t
erc-fill-mode: t
erc-stamp--date-mode: t
erc-stamp--display-margin-mode: t
erc-stamp-mode: t
erc-bufbar-mode: t
erc-track-mode: (t erc-nicks--setup-track-integration)
erc-track-minor-mode: t
erc-match-mode: t
erc-autojoin-mode: t
erc-autoaway-mode: t
recentf-mode: t
pixel-scroll-precision-mode: t
minibuffer-depth-indicate-mode: t
global-whitespace-mode: t
global-goto-address-mode: t
goto-address-mode: t
global-auto-revert-mode: t
fido-vertical-mode: t
icomplete-vertical-mode: t
icomplete-mode: t
fido-mode: t
erc-networks-mode: t
desktop-save-mode: t
windmove-mode: t
tooltip-mode: t
global-eldoc-mode: t
show-paren-mode: t
electric-indent-mode: t
mouse-wheel-mode: t
file-name-shadow-mode: t
global-font-lock-mode: t
font-lock-mode: t
blink-cursor-mode: t
column-number-mode: t
line-number-mode: t
visual-line-mode: t
indent-tabs-mode: t
transient-mark-mode: t
auto-composition-mode: t
auto-encryption-mode: t
auto-compression-mode: t
Features:
(shadow sort mail-extr emacsbug mule-util hl-line network-stream nsm
transient edmacro kmacro display-line-numbers org-element org-persist
org-id org-refile avl-tree generator oc-basic ol-eww eww xdg url-queue
mm-url ol-rmail ol-mhe ol-irc ol-info ol-gnus nnselect gnus-art mm-uu
mml2015 mm-view mml-smime smime gnutls dig gnus-sum shr pixel-fill
kinsoku url-file svg dom gnus-group gnus-undo gnus-start gnus-dbus
gnus-cloud nnimap nnmail mail-source utf7 nnoo parse-time gnus-spec
gnus-int gnus-range message sendmail yank-media puny rfc822 mml mml-sec
epa derived epg rfc6068 epg-config mm-decode mm-bodies mm-encode
mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev gmm-utils
mailheader gnus-win gnus nnheader gnus-util text-property-search
mail-utils range mm-util mail-prsvr ol-docview doc-view jka-compr
image-mode exif dired dired-loaddefs ol-bibtex bibtex iso8601 ol-bbdb
ol-w3m ol-doi org-link-doi org ob ob-tangle ob-ref ob-lob ob-table
ob-exp org-macro org-src ob-comint org-pcomplete org-list org-footnote
org-faces org-entities noutline outline ob-emacs-lisp ob-core ob-eval
org-cycle org-table ol org-fold org-fold-core org-keys oc org-loaddefs
find-func cal-menu calendar cal-loaddefs org-version org-compat org-macs
disp-table erc-ring erc-desktop-notifications notifications dbus xml
erc-nicks color erc-netsplit erc-menu erc-list erc-goodies erc-imenu
imenu erc-pcomplete time-date pcomplete comint ansi-osc ansi-color
erc-button erc-fill erc-stamp erc-status-sidebar erc-track erc-match
erc-join erc-autoaway leuven-dark-theme recentf tree-widget wid-edit
pixel-scroll cua-base ring mb-depth whitespace goto-addr thingatpt
autorevert filenotify icomplete erc format-spec erc-backend erc-networks
erc-common erc-compat compat erc-loaddefs desktop frameset cus-load
windmove site-start comp comp-cstr warnings icons rx cl-extra help-mode
erc-autoloads info compat-autoloads markdown-mode-autoloads package
browse-url url url-proxy url-privacy url-expand url-methods url-history
url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers
url-parse auth-source cl-seq eieio eieio-core cl-macs password-cache
json subr-x map byte-opt gv bytecomp byte-compile url-vars cl-loaddefs
cl-lib rmc iso-transl tooltip cconv eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty
make-network-process native-compile emacs)
Memory information:
((conses 16 397463 44016)
(symbols 48 27808 0)
(strings 32 98182 4397)
(string-bytes 1 3015974)
(vectors 16 52846)
(vector-slots 8 919020 87741)
(floats 8 532 941)
(intervals 56 4698 372)
(buffers 984 16))
[-- Attachment #2: 0001-erc-format-spoilers-Add-a-new-custom.patch --]
[-- Type: text/x-patch, Size: 1378 bytes --]
From 4d3b8fa17a975d6f04ba2a6ef4865d3938a76315 Mon Sep 17 00:00:00 2001
From: "F. Moukayed" <smfadi+emacs@gmail.com>
Date: Wed, 6 Mar 2024 18:33:46 +0000
Subject: [PATCH] * lisp/erc/erc.el: (erc-format-spoilers): Add a new
customizable variable controling how Erc displays spoilers
---
lisp/erc/erc-goodies.el | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 7e30b10..211d704 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -645,6 +645,11 @@ emergency (message flood) it can be turned off to save processing time. See
(defcustom erc-interpret-mirc-color nil
"If non-nil, ERC will interpret mIRC color codes."
+ :type 'boolean
+ :group 'erc-control-characters)
+
+(defcustom erc-format-spoilers nil
+ "If non-nil, ERC will format spoilers with `erc-spoiler-face'."
:type 'boolean)
(defcustom erc-beep-p nil
@@ -968,7 +973,7 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (if (and fg bg (equal fg bg))
+ (if (and fg bg (equal fg bg) erc-format-spoilers)
(progn
(setq fg 'erc-spoiler-face
bg nil)
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
2024-03-06 19:26 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers Fadi Moukayed
@ 2024-03-07 20:29 ` J.P.
[not found] ` <87v85xn5uv.fsf@neverwas.me>
1 sibling, 0 replies; 10+ messages in thread
From: J.P. @ 2024-03-07 20:29 UTC (permalink / raw)
To: Fadi Moukayed; +Cc: emacs-erc, 69597
Hi Fadi,
Fadi Moukayed <smfadi@gmail.com> writes:
> Tags: patch
> Severity: wishlist
>
> Hi all,
>
> I am submitting a trivial patch adding a simple customizable variable
> (erc-format-spoilers) to Erc, allowing the user to control how Erc
> displays spoiler text when mIRC formatting code interpretation is
> enabled.
> This idea for this patch was discussed with the Erc maintainers on
> #erc, and was deemed to be useful enough to warrant a submission.
>
> Note that this is my first attempt to contribute to GNU Emacs.
Welcome! I think this would make a helpful addition.
However, I'm also starting to wonder if the way `erc-spoiler-face'
currently operates doesn't constitute buggy behavior. Skimming the
related commits and nonexistent discussion history, I see no clear
indication as to motivation or reasoning, making me think it was just
chucked in on a whim. Frankly, it calls into question the fitness of all
involved (ahem). Really, though, the only legitimate use case that comes
to mind is possibly emphasizing the presence of spoilers when an
IRC-formatted fg/bg combo matches the buffer's own defaults, meaning the
span might otherwise be mistaken for whitespace. But that doesn't seem
like a common occurrence, and I doubt anyone would intentionally make
`fg:erc-color-face0' or `fg:erc-color-face1' match `erc-default-face' or
the `default' face's :background.
So, basically, I wonder if we shouldn't (instead?) just redefine the
face's role to be one of indicating _revealed_ text, which is currently
the job of `erc-inverse-face' (`erc-spoilers-face' could just :inherit
it). And FWIW, a change like this would be justifiable without much fuss
if we deemed it a bug fix, since this feature hasn't made it into any
releases yet.
Another (competing) idea would be to instead have the option specify a
regexp pattern along with color combinations that ERC could use to
determine if a candidate is likely spoiler text, which would then be
shown accordingly. Somehow, though, I'm rather dubious anyone would
actually bother configuring such a thing.
(Also, on a related note, we should probably add a `cursor-face'
property to complement the `mouse-face' one currently added to spoilers
and maybe also mention `cursor-face-highlight-mode' in the doc string.)
Anyhow, I'm not suggesting you need to take on any of what I've just
mentioned, especially with the fifteen-line limit in effect (unless of
course your paperwork comes through in record time or you're feeling up
for the challenge). That said, I'd still like your input on these
matters if you don't mind. From the Transient project you shared and our
wider discussion in the channel, it's clear you've thought more about
this stuff than anyone else around, especially these days.
J.P.
> In GNU Emacs 29.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.20,
> cairo version 1.16.0) of 2024-02-27 built on lcy02-amd64-095
[...]
>
> From 4d3b8fa17a975d6f04ba2a6ef4865d3938a76315 Mon Sep 17 00:00:00 2001
> From: "F. Moukayed" <smfadi+emacs@gmail.com>
> Date: Wed, 6 Mar 2024 18:33:46 +0000
> Subject: [PATCH] * lisp/erc/erc.el: (erc-format-spoilers): Add a new
> customizable variable controling how Erc displays spoilers
^
>
> ---
> lisp/erc/erc-goodies.el | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
> index 7e30b10..211d704 100644
> --- a/lisp/erc/erc-goodies.el
> +++ b/lisp/erc/erc-goodies.el
> @@ -645,6 +645,11 @@ emergency (message flood) it can be turned off to save processing time. See
>
> (defcustom erc-interpret-mirc-color nil
> "If non-nil, ERC will interpret mIRC color codes."
> + :type 'boolean
> + :group 'erc-control-characters)
> +
> +(defcustom erc-format-spoilers nil
> + "If non-nil, ERC will format spoilers with `erc-spoiler-face'."
> :type 'boolean)
>
> (defcustom erc-beep-p nil
> @@ -968,7 +973,7 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
> "Prepend properties from IRC control characters between FROM and TO.
> If optional argument STR is provided, apply to STR, otherwise prepend properties
> to a region in the current buffer."
> - (if (and fg bg (equal fg bg))
> + (if (and fg bg (equal fg bg) erc-format-spoilers)
> (progn
> (setq fg 'erc-spoiler-face
> bg nil)
P.S. These changes look fine, I think.
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <87v85xn5uv.fsf@neverwas.me>
@ 2024-03-08 9:07 ` Fadi Moukayed
[not found] ` <CAG_cVu_41w7VufKhJdaWEinQ-fyB22SULmyS0Gx9y+VgjGfYAQ@mail.gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Fadi Moukayed @ 2024-03-08 9:07 UTC (permalink / raw)
To: J.P.; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 6543 bytes --]
> So, basically, I wonder if we shouldn't (instead?) just redefine the
> face's role to be one of indicating _revealed_ text, which is currently
> the job of `erc-inverse-face' (`erc-spoilers-face' could just :inherit
> it). And FWIW, a change like this would be justifiable without much fuss
> if we deemed it a bug fix, since this feature hasn't made it into any
> releases yet.
After pondering this issue for a day or two, I've come around to agree
with this assessment. My gut feeling is that the KISS (as in "Keep It
Simple") solution would be to go the :inherit route and to reveal any
spoilers on user interaction.
Aside from changing the definition of the face, this would entail a
small modification/simplification in `erc-controls-propertize', where
the already-existing `put-text-property' calls is changed to set
'mouse-face to 'erc-spoiler-face. An illustrative patch doing this
change is included.
**However**, this is where I've seemingly hit another bug in Erc.
While setting 'mouse-face should - in theory - work, and cause the
propertized text to get revealed on mouse hover, in practice, it does
not. Some part of Erc's formatting machinery seems to strip away the
'mouse-face property off the text, so it does seem like the
`put-text-property' call in `erc-controls-propertize' has never really
worked for quite some time. Or at least, this is what I observe on my
own Emacs setup – would be helpful if others can confirm this
behavior.
Unfortunately, I haven't managed to find exactly where there the
'mouse-face property is removed, which is why I've termed the attached
patch "illustrative", aka. it does not quite resolve the issue fully.
Some help here would be appreciated.
Cheers,
FM.
Am Do., 7. März 2024 um 21:29 Uhr schrieb J.P. <jp@neverwas.me>:
>
> Hi Fadi,
>
> Fadi Moukayed <smfadi@gmail.com> writes:
>
> > Tags: patch
> > Severity: wishlist
> >
> > Hi all,
> >
> > I am submitting a trivial patch adding a simple customizable variable
> > (erc-format-spoilers) to Erc, allowing the user to control how Erc
> > displays spoiler text when mIRC formatting code interpretation is
> > enabled.
> > This idea for this patch was discussed with the Erc maintainers on
> > #erc, and was deemed to be useful enough to warrant a submission.
> >
> > Note that this is my first attempt to contribute to GNU Emacs.
>
> Welcome! I think this would make a helpful addition.
>
> However, I'm also starting to wonder if the way `erc-spoiler-face'
> currently operates doesn't constitute buggy behavior. Skimming the
> related commits and nonexistent discussion history, I see no clear
> indication as to motivation or reasoning, making me think it was just
> chucked in on a whim. Frankly, it calls into question the fitness of all
> involved (ahem). Really, though, the only legitimate use case that comes
> to mind is possibly emphasizing the presence of spoilers when an
> IRC-formatted fg/bg combo matches the buffer's own defaults, meaning the
> span might otherwise be mistaken for whitespace. But that doesn't seem
> like a common occurrence, and I doubt anyone would intentionally make
> `fg:erc-color-face0' or `fg:erc-color-face1' match `erc-default-face' or
> the `default' face's :background.
>
> So, basically, I wonder if we shouldn't (instead?) just redefine the
> face's role to be one of indicating _revealed_ text, which is currently
> the job of `erc-inverse-face' (`erc-spoilers-face' could just :inherit
> it). And FWIW, a change like this would be justifiable without much fuss
> if we deemed it a bug fix, since this feature hasn't made it into any
> releases yet.
>
> Another (competing) idea would be to instead have the option specify a
> regexp pattern along with color combinations that ERC could use to
> determine if a candidate is likely spoiler text, which would then be
> shown accordingly. Somehow, though, I'm rather dubious anyone would
> actually bother configuring such a thing.
>
> (Also, on a related note, we should probably add a `cursor-face'
> property to complement the `mouse-face' one currently added to spoilers
> and maybe also mention `cursor-face-highlight-mode' in the doc string.)
>
> Anyhow, I'm not suggesting you need to take on any of what I've just
> mentioned, especially with the fifteen-line limit in effect (unless of
> course your paperwork comes through in record time or you're feeling up
> for the challenge). That said, I'd still like your input on these
> matters if you don't mind. From the Transient project you shared and our
> wider discussion in the channel, it's clear you've thought more about
> this stuff than anyone else around, especially these days.
>
> J.P.
>
> > In GNU Emacs 29.2 (build 2, x86_64-pc-linux-gnu, GTK+ Version 3.24.20,
> > cairo version 1.16.0) of 2024-02-27 built on lcy02-amd64-095
> [...]
> >
> > From 4d3b8fa17a975d6f04ba2a6ef4865d3938a76315 Mon Sep 17 00:00:00 2001
> > From: "F. Moukayed" <smfadi+emacs@gmail.com>
> > Date: Wed, 6 Mar 2024 18:33:46 +0000
> > Subject: [PATCH] * lisp/erc/erc.el: (erc-format-spoilers): Add a new
> > customizable variable controling how Erc displays spoilers
> ^
> >
> > ---
> > lisp/erc/erc-goodies.el | 7 ++++++-
> > 1 file changed, 6 insertions(+), 1 deletion(-)
> >
> > diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
> > index 7e30b10..211d704 100644
> > --- a/lisp/erc/erc-goodies.el
> > +++ b/lisp/erc/erc-goodies.el
> > @@ -645,6 +645,11 @@ emergency (message flood) it can be turned off to save processing time. See
> >
> > (defcustom erc-interpret-mirc-color nil
> > "If non-nil, ERC will interpret mIRC color codes."
> > + :type 'boolean
> > + :group 'erc-control-characters)
> > +
> > +(defcustom erc-format-spoilers nil
> > + "If non-nil, ERC will format spoilers with `erc-spoiler-face'."
> > :type 'boolean)
> >
> > (defcustom erc-beep-p nil
> > @@ -968,7 +973,7 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
> > "Prepend properties from IRC control characters between FROM and TO.
> > If optional argument STR is provided, apply to STR, otherwise prepend properties
> > to a region in the current buffer."
> > - (if (and fg bg (equal fg bg))
> > + (if (and fg bg (equal fg bg) erc-format-spoilers)
> > (progn
> > (setq fg 'erc-spoiler-face
> > bg nil)
>
> P.S. These changes look fine, I think.
>
[-- Attachment #2: 0001-lisp-erc-erc-goodies-redefine-rework-erc-spoilers.patch --]
[-- Type: text/x-patch, Size: 1771 bytes --]
From 06e008d1de8a85c9e6b9a5a83f5ec5aefeb446c3 Mon Sep 17 00:00:00 2001
From: "F. Moukayed" <smfadi+emacs@gmail.com>
Date: Fri, 8 Mar 2024 08:39:03 +0000
Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
`erc-spoilers-face' to indicate revealed text
---
lisp/erc/erc-goodies.el | 15 +++++----------
1 file changed, 5 insertions(+), 10 deletions(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 7e30b10..12f7f3c 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -665,9 +665,7 @@ The value `erc-interpret-controls-p' must also be t for this to work."
"ERC inverse face."
:group 'erc-faces)
-(defface erc-spoiler-face
- '((((background light)) :foreground "DimGray" :background "DimGray")
- (((background dark)) :foreground "LightGray" :background "LightGray"))
+(defface erc-spoiler-face '((t :inherit (erc-inverse-face)))
"ERC spoiler face."
:group 'erc-faces)
@@ -968,13 +966,10 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (if (and fg bg (equal fg bg))
- (progn
- (setq fg 'erc-spoiler-face
- bg nil)
- (put-text-property from to 'mouse-face 'erc-inverse-face str))
- (when fg (setq fg (erc-get-fg-color-face fg)))
- (when bg (setq bg (erc-get-bg-color-face bg))))
+ (when (and fg bg (equal fg bg))
+ (put-text-property from to 'mouse-face 'erc-spoiler-face str))
+ (when fg (setq fg (erc-get-fg-color-face fg)))
+ (when bg (setq bg (erc-get-bg-color-face bg)))
(font-lock-prepend-text-property
from
to
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <CAG_cVu_41w7VufKhJdaWEinQ-fyB22SULmyS0Gx9y+VgjGfYAQ@mail.gmail.com>
@ 2024-03-08 15:05 ` J.P.
[not found] ` <87y1askbmr.fsf@neverwas.me>
1 sibling, 0 replies; 10+ messages in thread
From: J.P. @ 2024-03-08 15:05 UTC (permalink / raw)
To: Fadi Moukayed; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 5606 bytes --]
Fadi Moukayed <smfadi@gmail.com> writes:
>> So, basically, I wonder if we shouldn't (instead?) just redefine the
>> face's role to be one of indicating _revealed_ text, which is currently
>> the job of `erc-inverse-face' (`erc-spoilers-face' could just :inherit
>> it). And FWIW, a change like this would be justifiable without much fuss
>> if we deemed it a bug fix, since this feature hasn't made it into any
>> releases yet.
>
> After pondering this issue for a day or two, I've come around to agree
> with this assessment. My gut feeling is that the KISS (as in "Keep It
> Simple") solution would be to go the :inherit route and to reveal any
> spoilers on user interaction.
> Aside from changing the definition of the face, this would entail a
> small modification/simplification in `erc-controls-propertize', where
> the already-existing `put-text-property' calls is changed to set
> 'mouse-face to 'erc-spoiler-face. An illustrative patch doing this
> change is included.
Makes sense to me.
> **However**, this is where I've seemingly hit another bug in Erc.
> While setting 'mouse-face should - in theory - work, and cause the
> propertized text to get revealed on mouse hover, in practice, it does
> not. Some part of Erc's formatting machinery seems to strip away the
> 'mouse-face property off the text, so it does seem like the
> `put-text-property' call in `erc-controls-propertize' has never really
> worked for quite some time.
Your suspicions are likely spot on. Sad as it is, I don't think this
"feature" has _ever_ worked, especially if the unit test is anything to
go by. Basically, if I remove a lazy contrivance from the test
environment so it better reflects reality, the thing fails with exactly
the behavior you describe. FWIW, I've attached an improved version that
no longer suffers from this problem.
> Or at least, this is what I observe on my
> own Emacs setup – would be helpful if others can confirm this
> behavior.
>
> Unfortunately, I haven't managed to find exactly where there the
> 'mouse-face property is removed, which is why I've termed the attached
> patch "illustrative", aka. it does not quite resolve the issue fully.
> Some help here would be appreciated.
Ugh, sorry to have put you through all that. I've gone ahead and
attached a preliminary proposal for addressing the situation. If it
seems rather roundabout, it definitely is. Basically, we can't really
responsibly move `erc-controls-highlight' after `erc-button-add-buttons'
in `erc-insert-modify-hook' without causing general mayhem. So, absent a
smarter way to reconcile various interests (many of them legacy)
contending for the same real estate (e.g., `mouse-face'), we'll likely
have little choice but to settle for something in the vicinity of where
I've ended up (although I'd love to be wrong about that).
>
> Cheers,
> FM.
[...]
>>
>
> From 06e008d1de8a85c9e6b9a5a83f5ec5aefeb446c3 Mon Sep 17 00:00:00 2001
> From: "F. Moukayed" <smfadi+emacs@gmail.com>
> Date: Fri, 8 Mar 2024 08:39:03 +0000
> Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
> `erc-spoilers-face' to indicate revealed text
>
> ---
> lisp/erc/erc-goodies.el | 15 +++++----------
> 1 file changed, 5 insertions(+), 10 deletions(-)
>
> diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
> index 7e30b10..12f7f3c 100644
> --- a/lisp/erc/erc-goodies.el
> +++ b/lisp/erc/erc-goodies.el
> @@ -665,9 +665,7 @@ The value `erc-interpret-controls-p' must also be t for this to work."
> "ERC inverse face."
> :group 'erc-faces)
>
> -(defface erc-spoiler-face
> - '((((background light)) :foreground "DimGray" :background "DimGray")
> - (((background dark)) :foreground "LightGray" :background "LightGray"))
> +(defface erc-spoiler-face '((t :inherit (erc-inverse-face)))
> "ERC spoiler face."
> :group 'erc-faces)
>
> @@ -968,13 +966,10 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
> "Prepend properties from IRC control characters between FROM and TO.
> If optional argument STR is provided, apply to STR, otherwise prepend properties
> to a region in the current buffer."
> - (if (and fg bg (equal fg bg))
> - (progn
> - (setq fg 'erc-spoiler-face
> - bg nil)
> - (put-text-property from to 'mouse-face 'erc-inverse-face str))
> - (when fg (setq fg (erc-get-fg-color-face fg)))
> - (when bg (setq bg (erc-get-bg-color-face bg))))
> + (when (and fg bg (equal fg bg))
> + (put-text-property from to 'mouse-face 'erc-spoiler-face str))
Here's how I envision this working. So, in addition to your
`put-text-property' above, you'd have something like this:
(erc--reserve-important-text-props from to
'( mouse-face erc-spoiler-face
cursor-face erc-spoiler-face))
If you want, you can add `cursor-face' as well, so people without mice
can optionally use the feature:
(add-text-properties from to '( mouse-face erc-spoiler-face
cursor-face erc-spoiler-face)))
Please take a look at and (if possible) try the changes when you have a
chance. Happy to explain whatever doesn't make sense. And, obviously, if
you have any improvements or a superior solution, please don't hesitate.
Many thanks, as always.
> + (when fg (setq fg (erc-get-fg-color-face fg)))
> + (when bg (setq bg (erc-get-bg-color-face bg)))
> (font-lock-prepend-text-property
> from
> to
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-5.6-Fix-misleading-test-in-erc-goodies.patch --]
[-- Type: text/x-patch, Size: 3780 bytes --]
From f5473bd8c8fba7c5685f1a4cadb6e6f3eb9c6f27 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:11 -0800
Subject: [PATCH 1/2] [5.6] Fix misleading test in erc-goodies
* test/lisp/erc/erc-goodies-tests.el
(erc-controls-highlight--inverse): Don't shadow hook with an
unrealistic subset of members, in this case a lone member:
`erc-controls-highlight'. Adjust expected buffer state to reflect new
role of `erc-spoiler-face'. (Bug#69597)
---
test/lisp/erc/erc-goodies-tests.el | 60 +++++++++++++++---------------
1 file changed, 29 insertions(+), 31 deletions(-)
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index 7013ce0c8fc..ddc29acff1e 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -131,37 +131,35 @@ erc-controls-highlight--examples
(ert-deftest erc-controls-highlight--inverse ()
(should (eq t erc-interpret-controls-p))
- (let ((erc-insert-modify-hook '(erc-controls-highlight))
- erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
- (with-current-buffer (get-buffer-create "#chan")
- (erc-mode)
- (setq-local erc-interpret-mirc-color t)
- (erc--initialize-markers (point) nil)
-
- (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
- (msg (erc-format-privmessage "bob" m nil t)))
- (erc-display-message nil nil (current-buffer) msg))
- (forward-line -1)
- (should (search-forward "<bob> " nil t))
- (save-restriction
- (narrow-to-region (point) (pos-eol))
- (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
- 'erc-inverse-face))
- (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
- 'erc-inverse-face))
- (erc-goodies-tests--assert-face
- 0 "Spoiler: " 'erc-default-face
- '(fg:erc-color-face0 bg:erc-color-face0))
- (erc-goodies-tests--assert-face
- 9 "Hello" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1))
- (erc-goodies-tests--assert-face
- 18 " World" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1 )))
- (when noninteractive
- (kill-buffer)))))
+ (erc-tests-common-make-server-buf)
+ (with-current-buffer (erc--open-target "#chan")
+ (setq-local erc-interpret-mirc-color t)
+ (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
+ (msg (erc-format-privmessage "bob" m nil t)))
+ (erc-display-message nil nil (current-buffer) msg))
+ (forward-line -1)
+ (should (search-forward "<bob> " nil t))
+ (save-restriction
+ ;; Narrow to EOL or start of right-side stamp.
+ (narrow-to-region (point) (line-end-position))
+ (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
+ 'erc-spoiler-face))
+ (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
+ 'erc-spoiler-face))
+ ;; "Spoiler" appears in ERC default face.
+ (erc-goodies-tests--assert-face
+ 0 "Spoiler: " 'erc-default-face
+ '(fg:erc-color-face0 bg:erc-color-face0))
+ ;; "Hello" is masked in all white.
+ (erc-goodies-tests--assert-face
+ 9 "Hello" '(fg:erc-color-face0 bg:erc-color-face0)
+ '(fg:erc-color-face1 bg:erc-color-face1))
+ ;; "World" is masked in all black.
+ (erc-goodies-tests--assert-face
+ 18 " World" '(fg:erc-color-face1 bg:erc-color-face1 )
+ '(fg:erc-color-face0 bg:erc-color-face0))))
+ (when noninteractive
+ (erc-tests-common-kill-buffers)))
(defvar erc-goodies-tests--motd
;; This is from ergo's MOTD
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0002-5.6-Make-important-text-props-more-resilient-in-ERC.patch --]
[-- Type: text/x-patch, Size: 6246 bytes --]
From a66abc007c071f224b459cffdc2a451e36a80903 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:23 -0800
Subject: [PATCH 2/2] [5.6] Make important text props more resilient in ERC
* lisp/erc/erc-button.el (erc-button-remove-old-buttons): Restore
original `mouse-face' values in areas marked as important after
clobbering.
* lisp/erc/erc.el (erc--reserve-important-text-props): New function.
(erc--restore-important-text-props): New function.
* test/lisp/erc/erc-tests.el
(erc--restore-important-text-props): New test.
(Bug#69597)
---
lisp/erc/erc-button.el | 3 ++-
lisp/erc/erc.el | 32 +++++++++++++++++++++++
test/lisp/erc/erc-tests.el | 52 ++++++++++++++++++++++++++++++++++++++
3 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 6b78e451b54..4b4930e5bff 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -528,7 +528,8 @@ erc-button-remove-old-buttons
'(erc-callback nil
erc-data nil
mouse-face nil
- keymap nil)))
+ keymap nil))
+ (erc--restore-important-text-props '(mouse-face)))
(defun erc-button-add-button (from to fun nick-p &optional data regexp)
"Create a button between FROM and TO with callback FUN and data DATA.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index cce3b2508fb..49b51c5d74c 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3532,6 +3532,38 @@ erc--remove-from-prop-value-list
old (get-text-property pos prop object)
end (next-single-property-change pos prop object to)))))
+(defun erc--reserve-important-text-props (beg end plist)
+ "Record text-property pairs in PLIST as important between BEG and END.
+Also mark the message being inserted as containing these important props
+so modules performing destructive modifications can later restore them.
+Expect to run in a narrowed buffer at message-insertion time."
+ (when erc--msg-props
+ (let ((existing (erc--check-msg-prop 'erc--important-prop-names)))
+ (puthash 'erc--important-prop-names
+ (seq-union existing (cl-loop for (key _) on plist by #'cddr
+ collect key))
+ erc--msg-props)))
+ (erc--merge-prop beg end 'erc--important-props plist))
+
+;; FIXME use a region instead of point-min/max.
+(defun erc--restore-important-text-props (props)
+ "Restore PROPS where recorded in the accessible portion of the buffer.
+Expect to run in a narrowed buffer at message-insertion time."
+ (when-let ((registered (erc--check-msg-prop 'erc--important-prop-names))
+ (present (seq-intersection props registered))
+ (p (point-min))
+ (end (point-max)))
+ (while-let (((setq p (text-property-not-all p end
+ 'erc--important-props nil)))
+ (val (get-text-property p 'erc--important-props))
+ (q (next-single-property-change p 'erc--important-props
+ nil end)))
+ (while-let ((k (pop val))
+ (v (pop val)))
+ (when (memq k present)
+ (put-text-property p q k v)))
+ (setq p q))))
+
(defvar erc-legacy-invisible-bounds-p nil
"Whether to hide trailing rather than preceding newlines.
Beginning in ERC 5.6, invisibility extends from a message's
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 085b063bdb2..6809d9db41d 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -2232,6 +2232,58 @@ erc--remove-from-prop-value-list/many
(when noninteractive
(kill-buffer))))
+(ert-deftest erc--restore-important-text-props ()
+ (erc-mode)
+ (let ((erc--msg-props (map-into '((erc--important-prop-names a))
+ 'hash-table)))
+ (insert (propertize "foo" 'a 'A 'b 'B 'erc--important-props '(a A))
+ " "
+ (propertize "bar" 'c 'C 'a 'A 'b 'B
+ 'erc--important-props '(a A c C)))
+
+ ;; Attempt to restore a and c when only a is registered.
+ (remove-list-of-text-properties (point-min) (point-max) '(a c))
+ (erc--restore-important-text-props '(a c))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 3 (a A b B erc--important-props (a A))
+ 4 7 (a A b B erc--important-props (a A c C)))))
+
+ ;; Add d between 3 and 6.
+ (erc--reserve-important-text-props 3 6 '(d D))
+ (put-text-property 3 6 'd 'D)
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; #1
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))
+ ;; Remove a and d, and attempt to restore d.
+ (remove-list-of-text-properties (point-min) (point-max) '(a d))
+ (erc--restore-important-text-props '(d))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 2 (b B erc--important-props (a A))
+ 2 3 (d D b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D b B erc--important-props (d D a A c C))
+ 5 7 (b B erc--important-props (a A c C)))))
+
+ ;; Restore a only.
+ (erc--restore-important-text-props '(a))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; same as #1 above
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))))
+
(ert-deftest erc--split-string-shell-cmd ()
;; Leading and trailing space
--
2.44.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <87y1askbmr.fsf@neverwas.me>
@ 2024-03-08 16:47 ` Fadi Moukayed
[not found] ` <CAG_cVu_Jcgk2KRbx7g_dZzsWjE-PQHJwCQuZGSYMV7ZFLZ4qEw@mail.gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Fadi Moukayed @ 2024-03-08 16:47 UTC (permalink / raw)
To: J.P.; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 7371 bytes --]
Thanks JP,
Good news: With both of your patches applied (and including the
revised patch for erc-goodies.el, attached to this message), things
seem to behave exactly as expected. Spoilers are displayed correctly,
and hovering the mouse on them causes them to get revealed as
`erc-spoiler-face'.
The only issue I noticed after applying the patches, is that the
following warning is emitted on the *Messages* buffer – (Note that I
have native compilation enabled):
> ⛔ Warning (comp): erc-button.el:532:4: Warning: the function ‘erc--restore-important-text-props’ is not known to be defined.
I assume this is a compilation order issue? Note that this only
happens with a clean ELN cache (The following Emacs loads are fine),
so not sure how significant it is.
>Happy to explain whatever doesn't make sense
One question regarding "FIXME use a region instead of point-min/max"
in patch #0002, is there a reason why (region-beginning) /
(region-end) is indeed not used instead? Just mentioning that because
IIRC, point-{min,max} is a range over the entire (narrowed) buffer,
including the (buttonized) nick, message text, possible timestamp (if
activated) as well. I checked the properties on the whole message line
while testing and it doesn't seem to have any negative side-effects,
aside from the fact that it operates on more text than it has to – I
believe it need only be applied to the message text.
Cheers,
FM
Am Fr., 8. März 2024 um 16:05 Uhr schrieb J.P. <jp@neverwas.me>:
>
> Fadi Moukayed <smfadi@gmail.com> writes:
>
> >> So, basically, I wonder if we shouldn't (instead?) just redefine the
> >> face's role to be one of indicating _revealed_ text, which is currently
> >> the job of `erc-inverse-face' (`erc-spoilers-face' could just :inherit
> >> it). And FWIW, a change like this would be justifiable without much fuss
> >> if we deemed it a bug fix, since this feature hasn't made it into any
> >> releases yet.
> >
> > After pondering this issue for a day or two, I've come around to agree
> > with this assessment. My gut feeling is that the KISS (as in "Keep It
> > Simple") solution would be to go the :inherit route and to reveal any
> > spoilers on user interaction.
> > Aside from changing the definition of the face, this would entail a
> > small modification/simplification in `erc-controls-propertize', where
> > the already-existing `put-text-property' calls is changed to set
> > 'mouse-face to 'erc-spoiler-face. An illustrative patch doing this
> > change is included.
>
> Makes sense to me.
>
> > **However**, this is where I've seemingly hit another bug in Erc.
> > While setting 'mouse-face should - in theory - work, and cause the
> > propertized text to get revealed on mouse hover, in practice, it does
> > not. Some part of Erc's formatting machinery seems to strip away the
> > 'mouse-face property off the text, so it does seem like the
> > `put-text-property' call in `erc-controls-propertize' has never really
> > worked for quite some time.
>
> Your suspicions are likely spot on. Sad as it is, I don't think this
> "feature" has _ever_ worked, especially if the unit test is anything to
> go by. Basically, if I remove a lazy contrivance from the test
> environment so it better reflects reality, the thing fails with exactly
> the behavior you describe. FWIW, I've attached an improved version that
> no longer suffers from this problem.
>
> > Or at least, this is what I observe on my
> > own Emacs setup – would be helpful if others can confirm this
> > behavior.
> >
> > Unfortunately, I haven't managed to find exactly where there the
> > 'mouse-face property is removed, which is why I've termed the attached
> > patch "illustrative", aka. it does not quite resolve the issue fully.
> > Some help here would be appreciated.
>
> Ugh, sorry to have put you through all that. I've gone ahead and
> attached a preliminary proposal for addressing the situation. If it
> seems rather roundabout, it definitely is. Basically, we can't really
> responsibly move `erc-controls-highlight' after `erc-button-add-buttons'
> in `erc-insert-modify-hook' without causing general mayhem. So, absent a
> smarter way to reconcile various interests (many of them legacy)
> contending for the same real estate (e.g., `mouse-face'), we'll likely
> have little choice but to settle for something in the vicinity of where
> I've ended up (although I'd love to be wrong about that).
>
> >
> > Cheers,
> > FM.
> [...]
> >>
> >
> > From 06e008d1de8a85c9e6b9a5a83f5ec5aefeb446c3 Mon Sep 17 00:00:00 2001
> > From: "F. Moukayed" <smfadi+emacs@gmail.com>
> > Date: Fri, 8 Mar 2024 08:39:03 +0000
> > Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
> > `erc-spoilers-face' to indicate revealed text
> >
> > ---
> > lisp/erc/erc-goodies.el | 15 +++++----------
> > 1 file changed, 5 insertions(+), 10 deletions(-)
> >
> > diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
> > index 7e30b10..12f7f3c 100644
> > --- a/lisp/erc/erc-goodies.el
> > +++ b/lisp/erc/erc-goodies.el
> > @@ -665,9 +665,7 @@ The value `erc-interpret-controls-p' must also be t for this to work."
> > "ERC inverse face."
> > :group 'erc-faces)
> >
> > -(defface erc-spoiler-face
> > - '((((background light)) :foreground "DimGray" :background "DimGray")
> > - (((background dark)) :foreground "LightGray" :background "LightGray"))
> > +(defface erc-spoiler-face '((t :inherit (erc-inverse-face)))
> > "ERC spoiler face."
> > :group 'erc-faces)
> >
> > @@ -968,13 +966,10 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
> > "Prepend properties from IRC control characters between FROM and TO.
> > If optional argument STR is provided, apply to STR, otherwise prepend properties
> > to a region in the current buffer."
> > - (if (and fg bg (equal fg bg))
> > - (progn
> > - (setq fg 'erc-spoiler-face
> > - bg nil)
> > - (put-text-property from to 'mouse-face 'erc-inverse-face str))
> > - (when fg (setq fg (erc-get-fg-color-face fg)))
> > - (when bg (setq bg (erc-get-bg-color-face bg))))
> > + (when (and fg bg (equal fg bg))
> > + (put-text-property from to 'mouse-face 'erc-spoiler-face str))
>
> Here's how I envision this working. So, in addition to your
> `put-text-property' above, you'd have something like this:
>
> (erc--reserve-important-text-props from to
> '( mouse-face erc-spoiler-face
> cursor-face erc-spoiler-face))
>
> If you want, you can add `cursor-face' as well, so people without mice
> can optionally use the feature:
>
> (add-text-properties from to '( mouse-face erc-spoiler-face
> cursor-face erc-spoiler-face)))
>
> Please take a look at and (if possible) try the changes when you have a
> chance. Happy to explain whatever doesn't make sense. And, obviously, if
> you have any improvements or a superior solution, please don't hesitate.
>
> Many thanks, as always.
>
> > + (when fg (setq fg (erc-get-fg-color-face fg)))
> > + (when bg (setq bg (erc-get-bg-color-face bg)))
> > (font-lock-prepend-text-property
> > from
> > to
>
[-- Attachment #2: 0001-erc-redefine-rework-erc-spoilers.patch --]
[-- Type: text/x-patch, Size: 2210 bytes --]
From ac0b308f6b300eb454ebdf9ba4526fac012f1a52 Mon Sep 17 00:00:00 2001
From: "F. Moukayed" <smfadi+emacs@gmail.com>
Date: Fri, 8 Mar 2024 08:39:03 +0000
Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
`erc-spoilers-face' to indicate revealed text
---
lisp/erc/erc-goodies.el | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 7e30b10..611fdbe 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -665,9 +665,7 @@ The value `erc-interpret-controls-p' must also be t for this to work."
"ERC inverse face."
:group 'erc-faces)
-(defface erc-spoiler-face
- '((((background light)) :foreground "DimGray" :background "DimGray")
- (((background dark)) :foreground "LightGray" :background "LightGray"))
+(defface erc-spoiler-face '((t :inherit erc-inverse-face))
"ERC spoiler face."
:group 'erc-faces)
@@ -968,13 +966,19 @@ Also see `erc-interpret-controls-p' and `erc-interpret-mirc-color'."
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (if (and fg bg (equal fg bg))
- (progn
- (setq fg 'erc-spoiler-face
- bg nil)
- (put-text-property from to 'mouse-face 'erc-inverse-face str))
- (when fg (setq fg (erc-get-fg-color-face fg)))
- (when bg (setq bg (erc-get-bg-color-face bg))))
+ (when (and fg bg (equal fg bg))
+ (add-text-properties from to '(mouse-face
+ erc-spoiler-face
+ cursor-face
+ erc-spoiler-face)
+ str))
+ (erc--reserve-important-text-props from to
+ '(mouse-face
+ erc-spoiler-face
+ cursor-face
+ erc-spoiler-face))
+ (when fg (setq fg (erc-get-fg-color-face fg)))
+ (when bg (setq bg (erc-get-bg-color-face bg)))
(font-lock-prepend-text-property
from
to
--
2.34.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <CAG_cVu_Jcgk2KRbx7g_dZzsWjE-PQHJwCQuZGSYMV7ZFLZ4qEw@mail.gmail.com>
@ 2024-03-09 4:43 ` J.P.
[not found] ` <87edckc8x2.fsf@neverwas.me>
1 sibling, 0 replies; 10+ messages in thread
From: J.P. @ 2024-03-09 4:43 UTC (permalink / raw)
To: Fadi Moukayed; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 3343 bytes --]
Fadi Moukayed <smfadi@gmail.com> writes:
> The only issue I noticed after applying the patches, is that the
> following warning is emitted on the *Messages* buffer – (Note that I
> have native compilation enabled):
>
>> ⛔ Warning (comp): erc-button.el:532:4: Warning: the function
>> ‘erc--restore-important-text-props’ is not known to be defined.
>
> I assume this is a compilation order issue? Note that this only
> happens with a clean ELN cache (The following Emacs loads are fine),
> so not sure how significant it is.
Hm, unless I messed something up (definitely possible), that shouldn't
happen . For ERC, I typically remove all the lisp/erc/*.elc files after
every change and before rerunning Make, regardless of whether native
comp is enabled (though removing native-lisp/30.0.50-deadbeef/*.eln
isn't usually necessary, AFAICT). Sometimes, though, I also have to
remove lisp/loaddefs.* and others. In case you weren't aware, there are
recipes for regenerating various autoloads and Custom business in
lisp/Makefile, but I usually just delete all stale assets completely.
>>Happy to explain whatever doesn't make sense
>
> One question regarding "FIXME use a region instead of point-min/max"
> in patch #0002, is there a reason why (region-beginning) /
> (region-end) is indeed not used instead? Just mentioning that because
> IIRC, point-{min,max} is a range over the entire (narrowed) buffer,
> including the (buttonized) nick, message text, possible timestamp (if
> activated) as well. I checked the properties on the whole message line
> while testing and it doesn't seem to have any negative side-effects,
> aside from the fact that it operates on more text than it has to – I
> believe it need only be applied to the message text.
Unfortunately, insertion-hook members lack a means for detecting message
boundaries unequivocally, although they can obviously keep track of
their own modifications and make assertions accordingly. So I agree that
allowing the caller to specify BEG and END in cases where they're
already known makes sense. For example, if they've already scanned for
the end of the speaker name to accomplish some other task or happen to
know the start of the right stamp, it's worth passing that knowledge
along. But computing a sub-region specially, beforehand, just to call
this function is likely less efficient (not that you were suggesting
that). And, of course, accepting BEG/END parameters make it easier to
protect areas of the exposed buffer from props restoration, if ever
there's a need.
>> > From 06e008d1de8a85c9e6b9a5a83f5ec5aefeb446c3 Mon Sep 17 00:00:00 2001
>> > From: "F. Moukayed" <smfadi+emacs@gmail.com>
>> > Date: Fri, 8 Mar 2024 08:39:03 +0000
>> > Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
>> > `erc-spoilers-face' to indicate revealed text
This is news to me, but apparently there's a Git hook that complains
about overlong subject lines. After running git-am(1) to apply your
latest patch, I saw:
Line longer than 78 characters in commit message
Commit aborted; please see the file CONTRIBUTE
So I adjusted the message to conform to this requirement. If the
attached changes look all right to you, then I'll install them (or
something similar) in the coming days.
Thanks,
J.P.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v1-v2.diff --]
[-- Type: text/x-patch, Size: 6254 bytes --]
From acc9d0c4c1394a6e52bf34c59318888d91d249a6 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Fri, 8 Mar 2024 17:45:54 -0800
Subject: [PATCH 0/3] *** NOT A PATCH ***
. Rename the test.
. Add `object' parameter to `erc--reserve-important-text-props'.
. Subject `erc--reserve-important-text-props' call site to the same guard
condition as `add-text-properties', so messages that don't include spoilers
aren't marked as having important props (thus allowing healing logic to
ignore those messages instead of scan them unnecessarily).
F. Jason Park (2):
[5.6] Fix misleading test in erc-goodies
[5.6] Make important text props more resilient in ERC
F. Moukayed (1):
[5.6] Redefine erc-spoilers-face to indicate revealed text
lisp/erc/erc-button.el | 3 +-
lisp/erc/erc-goodies.el | 21 +++++-----
lisp/erc/erc.el | 34 ++++++++++++++++
test/lisp/erc/erc-goodies-tests.el | 62 +++++++++++++++---------------
test/lisp/erc/erc-tests.el | 52 +++++++++++++++++++++++++
5 files changed, 129 insertions(+), 43 deletions(-)
Interdiff:
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 611fdbedf7b..212cdbfa9ef 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -967,16 +967,13 @@ erc-controls-propertize
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
(when (and fg bg (equal fg bg))
- (add-text-properties from to '(mouse-face
- erc-spoiler-face
- cursor-face
- erc-spoiler-face)
- str))
- (erc--reserve-important-text-props from to
- '(mouse-face
- erc-spoiler-face
- cursor-face
- erc-spoiler-face))
+ (add-text-properties from to '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str)
+ (erc--reserve-important-text-props from to
+ '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str))
(when fg (setq fg (erc-get-fg-color-face fg)))
(when bg (setq bg (erc-get-bg-color-face bg)))
(font-lock-prepend-text-property
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index 49b51c5d74c..08bc9939b9a 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3532,37 +3532,39 @@ erc--remove-from-prop-value-list
old (get-text-property pos prop object)
end (next-single-property-change pos prop object to)))))
-(defun erc--reserve-important-text-props (beg end plist)
+(defun erc--reserve-important-text-props (beg end plist &optional object)
"Record text-property pairs in PLIST as important between BEG and END.
Also mark the message being inserted as containing these important props
so modules performing destructive modifications can later restore them.
Expect to run in a narrowed buffer at message-insertion time."
(when erc--msg-props
(let ((existing (erc--check-msg-prop 'erc--important-prop-names)))
- (puthash 'erc--important-prop-names
- (seq-union existing (cl-loop for (key _) on plist by #'cddr
- collect key))
+ (puthash 'erc--important-prop-names (seq-union existing (map-keys plist))
erc--msg-props)))
- (erc--merge-prop beg end 'erc--important-props plist))
+ (erc--merge-prop beg end 'erc--important-props plist object))
-;; FIXME use a region instead of point-min/max.
-(defun erc--restore-important-text-props (props)
+(defun erc--restore-important-text-props (props &optional beg end)
"Restore PROPS where recorded in the accessible portion of the buffer.
-Expect to run in a narrowed buffer at message-insertion time."
+Expect to run in a narrowed buffer at message-insertion time. Limit the
+effect to the region between buffer positions BEG and END, when non-nil.
+
+Callers should be aware that this function fails if the property
+`erc--important-props' has an empty value almost anywhere along the
+affected region. Use the function `erc--remove-from-prop-value-list' to
+ensure that props with empty values are excised completely."
(when-let ((registered (erc--check-msg-prop 'erc--important-prop-names))
(present (seq-intersection props registered))
- (p (point-min))
- (end (point-max)))
- (while-let (((setq p (text-property-not-all p end
- 'erc--important-props nil)))
- (val (get-text-property p 'erc--important-props))
- (q (next-single-property-change p 'erc--important-props
- nil end)))
+ (b (or beg (point-min)))
+ (e (or end (point-max))))
+ (while-let
+ (((setq b (text-property-not-all b e 'erc--important-props nil)))
+ (val (get-text-property b 'erc--important-props))
+ (q (next-single-property-change b 'erc--important-props nil e)))
(while-let ((k (pop val))
(v (pop val)))
(when (memq k present)
- (put-text-property p q k v)))
- (setq p q))))
+ (put-text-property b q k v)))
+ (setq b q))))
(defvar erc-legacy-invisible-bounds-p nil
"Whether to hide trailing rather than preceding newlines.
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index ddc29acff1e..0ab40808a4a 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -129,7 +129,7 @@ erc-controls-highlight--examples
;; Hovering over the redacted area should reveal its underlying text
;; in a high-contrast face.
-(ert-deftest erc-controls-highlight--inverse ()
+(ert-deftest erc-controls-highlight--spoilers ()
(should (eq t erc-interpret-controls-p))
(erc-tests-common-make-server-buf)
(with-current-buffer (erc--open-target "#chan")
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-5.6-Fix-misleading-test-in-erc-goodies.patch --]
[-- Type: text/x-patch, Size: 4012 bytes --]
From 5ceebcb6718c8140ea58f659a3b295a12d9e9a4f Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:11 -0800
Subject: [PATCH 1/3] [5.6] Fix misleading test in erc-goodies
* test/lisp/erc/erc-goodies-tests.el
(erc-controls-highlight--inverse, erc-controls-highlight--spoilers):
Rename former to latter, and don't shadow `erc-insert-modify-hook'
with an unrealistic subset of members, in this case a lone member:
`erc-controls-highlight'. Adjust expected buffer state to reflect new
role of `erc-spoiler-face'. (Bug#69597)
---
test/lisp/erc/erc-goodies-tests.el | 62 +++++++++++++++---------------
1 file changed, 30 insertions(+), 32 deletions(-)
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index 7013ce0c8fc..0ab40808a4a 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -129,39 +129,37 @@ erc-controls-highlight--examples
;; Hovering over the redacted area should reveal its underlying text
;; in a high-contrast face.
-(ert-deftest erc-controls-highlight--inverse ()
+(ert-deftest erc-controls-highlight--spoilers ()
(should (eq t erc-interpret-controls-p))
- (let ((erc-insert-modify-hook '(erc-controls-highlight))
- erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
- (with-current-buffer (get-buffer-create "#chan")
- (erc-mode)
- (setq-local erc-interpret-mirc-color t)
- (erc--initialize-markers (point) nil)
-
- (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
- (msg (erc-format-privmessage "bob" m nil t)))
- (erc-display-message nil nil (current-buffer) msg))
- (forward-line -1)
- (should (search-forward "<bob> " nil t))
- (save-restriction
- (narrow-to-region (point) (pos-eol))
- (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
- 'erc-inverse-face))
- (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
- 'erc-inverse-face))
- (erc-goodies-tests--assert-face
- 0 "Spoiler: " 'erc-default-face
- '(fg:erc-color-face0 bg:erc-color-face0))
- (erc-goodies-tests--assert-face
- 9 "Hello" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1))
- (erc-goodies-tests--assert-face
- 18 " World" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1 )))
- (when noninteractive
- (kill-buffer)))))
+ (erc-tests-common-make-server-buf)
+ (with-current-buffer (erc--open-target "#chan")
+ (setq-local erc-interpret-mirc-color t)
+ (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
+ (msg (erc-format-privmessage "bob" m nil t)))
+ (erc-display-message nil nil (current-buffer) msg))
+ (forward-line -1)
+ (should (search-forward "<bob> " nil t))
+ (save-restriction
+ ;; Narrow to EOL or start of right-side stamp.
+ (narrow-to-region (point) (line-end-position))
+ (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
+ 'erc-spoiler-face))
+ (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
+ 'erc-spoiler-face))
+ ;; "Spoiler" appears in ERC default face.
+ (erc-goodies-tests--assert-face
+ 0 "Spoiler: " 'erc-default-face
+ '(fg:erc-color-face0 bg:erc-color-face0))
+ ;; "Hello" is masked in all white.
+ (erc-goodies-tests--assert-face
+ 9 "Hello" '(fg:erc-color-face0 bg:erc-color-face0)
+ '(fg:erc-color-face1 bg:erc-color-face1))
+ ;; "World" is masked in all black.
+ (erc-goodies-tests--assert-face
+ 18 " World" '(fg:erc-color-face1 bg:erc-color-face1 )
+ '(fg:erc-color-face0 bg:erc-color-face0))))
+ (when noninteractive
+ (erc-tests-common-kill-buffers)))
(defvar erc-goodies-tests--motd
;; This is from ergo's MOTD
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0002-5.6-Make-important-text-props-more-resilient-in-ERC.patch --]
[-- Type: text/x-patch, Size: 6410 bytes --]
From 9b5f8e0a85866ae9245a2b480183f6a36d23a413 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:23 -0800
Subject: [PATCH 2/3] [5.6] Make important text props more resilient in ERC
* lisp/erc/erc-button.el (erc-button-remove-old-buttons): Restore
original `mouse-face' values in areas marked as important after
clobbering.
* lisp/erc/erc.el (erc--reserve-important-text-props): New function.
(erc--restore-important-text-props): New function.
* test/lisp/erc/erc-tests.el
(erc--restore-important-text-props): New test.
(Bug#69597)
---
lisp/erc/erc-button.el | 3 ++-
lisp/erc/erc.el | 34 +++++++++++++++++++++++++
test/lisp/erc/erc-tests.el | 52 ++++++++++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 6b78e451b54..4b4930e5bff 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -528,7 +528,8 @@ erc-button-remove-old-buttons
'(erc-callback nil
erc-data nil
mouse-face nil
- keymap nil)))
+ keymap nil))
+ (erc--restore-important-text-props '(mouse-face)))
(defun erc-button-add-button (from to fun nick-p &optional data regexp)
"Create a button between FROM and TO with callback FUN and data DATA.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index cce3b2508fb..08bc9939b9a 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3532,6 +3532,40 @@ erc--remove-from-prop-value-list
old (get-text-property pos prop object)
end (next-single-property-change pos prop object to)))))
+(defun erc--reserve-important-text-props (beg end plist &optional object)
+ "Record text-property pairs in PLIST as important between BEG and END.
+Also mark the message being inserted as containing these important props
+so modules performing destructive modifications can later restore them.
+Expect to run in a narrowed buffer at message-insertion time."
+ (when erc--msg-props
+ (let ((existing (erc--check-msg-prop 'erc--important-prop-names)))
+ (puthash 'erc--important-prop-names (seq-union existing (map-keys plist))
+ erc--msg-props)))
+ (erc--merge-prop beg end 'erc--important-props plist object))
+
+(defun erc--restore-important-text-props (props &optional beg end)
+ "Restore PROPS where recorded in the accessible portion of the buffer.
+Expect to run in a narrowed buffer at message-insertion time. Limit the
+effect to the region between buffer positions BEG and END, when non-nil.
+
+Callers should be aware that this function fails if the property
+`erc--important-props' has an empty value almost anywhere along the
+affected region. Use the function `erc--remove-from-prop-value-list' to
+ensure that props with empty values are excised completely."
+ (when-let ((registered (erc--check-msg-prop 'erc--important-prop-names))
+ (present (seq-intersection props registered))
+ (b (or beg (point-min)))
+ (e (or end (point-max))))
+ (while-let
+ (((setq b (text-property-not-all b e 'erc--important-props nil)))
+ (val (get-text-property b 'erc--important-props))
+ (q (next-single-property-change b 'erc--important-props nil e)))
+ (while-let ((k (pop val))
+ (v (pop val)))
+ (when (memq k present)
+ (put-text-property b q k v)))
+ (setq b q))))
+
(defvar erc-legacy-invisible-bounds-p nil
"Whether to hide trailing rather than preceding newlines.
Beginning in ERC 5.6, invisibility extends from a message's
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 085b063bdb2..6809d9db41d 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -2232,6 +2232,58 @@ erc--remove-from-prop-value-list/many
(when noninteractive
(kill-buffer))))
+(ert-deftest erc--restore-important-text-props ()
+ (erc-mode)
+ (let ((erc--msg-props (map-into '((erc--important-prop-names a))
+ 'hash-table)))
+ (insert (propertize "foo" 'a 'A 'b 'B 'erc--important-props '(a A))
+ " "
+ (propertize "bar" 'c 'C 'a 'A 'b 'B
+ 'erc--important-props '(a A c C)))
+
+ ;; Attempt to restore a and c when only a is registered.
+ (remove-list-of-text-properties (point-min) (point-max) '(a c))
+ (erc--restore-important-text-props '(a c))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 3 (a A b B erc--important-props (a A))
+ 4 7 (a A b B erc--important-props (a A c C)))))
+
+ ;; Add d between 3 and 6.
+ (erc--reserve-important-text-props 3 6 '(d D))
+ (put-text-property 3 6 'd 'D)
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; #1
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))
+ ;; Remove a and d, and attempt to restore d.
+ (remove-list-of-text-properties (point-min) (point-max) '(a d))
+ (erc--restore-important-text-props '(d))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 2 (b B erc--important-props (a A))
+ 2 3 (d D b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D b B erc--important-props (d D a A c C))
+ 5 7 (b B erc--important-props (a A c C)))))
+
+ ;; Restore a only.
+ (erc--restore-important-text-props '(a))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; same as #1 above
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))))
+
(ert-deftest erc--split-string-shell-cmd ()
;; Leading and trailing space
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0003-5.6-Redefine-erc-spoilers-face-to-indicate-revealed-.patch --]
[-- Type: text/x-patch, Size: 2154 bytes --]
From acc9d0c4c1394a6e52bf34c59318888d91d249a6 Mon Sep 17 00:00:00 2001
From: "F. Moukayed" <smfadi+emacs@gmail.com>
Date: Fri, 8 Mar 2024 08:39:03 +0000
Subject: [PATCH 3/3] [5.6] Redefine erc-spoilers-face to indicate revealed
text
* lisp/erc/erc-goodies.el (erc-spoilers-face): Redefine role and
rework definition to inherit from `erc-inverse-face'.
(Bug#69597)
Copyright-paperwork-exempt: yes
---
lisp/erc/erc-goodies.el | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 7e30b1060fd..212cdbfa9ef 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -665,9 +665,7 @@ erc-inverse-face
"ERC inverse face."
:group 'erc-faces)
-(defface erc-spoiler-face
- '((((background light)) :foreground "DimGray" :background "DimGray")
- (((background dark)) :foreground "LightGray" :background "LightGray"))
+(defface erc-spoiler-face '((t :inherit erc-inverse-face))
"ERC spoiler face."
:group 'erc-faces)
@@ -968,13 +966,16 @@ erc-controls-propertize
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (if (and fg bg (equal fg bg))
- (progn
- (setq fg 'erc-spoiler-face
- bg nil)
- (put-text-property from to 'mouse-face 'erc-inverse-face str))
- (when fg (setq fg (erc-get-fg-color-face fg)))
- (when bg (setq bg (erc-get-bg-color-face bg))))
+ (when (and fg bg (equal fg bg))
+ (add-text-properties from to '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str)
+ (erc--reserve-important-text-props from to
+ '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str))
+ (when fg (setq fg (erc-get-fg-color-face fg)))
+ (when bg (setq bg (erc-get-bg-color-face bg)))
(font-lock-prepend-text-property
from
to
--
2.44.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <87edckc8x2.fsf@neverwas.me>
@ 2024-03-09 10:34 ` Fadi Moukayed
[not found] ` <CAG_cVu_gmo0Oc50y7pMTH8Nw_7JkWSMnOD9oZjYWLBiZa-GRfA@mail.gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Fadi Moukayed @ 2024-03-09 10:34 UTC (permalink / raw)
To: J.P.; +Cc: emacs-erc, 69597
>I typically remove all the lisp/erc/*.elc files
Thanks, this is what I missed. Deleting all *.elc files solves the
warning issue.
>So I adjusted the message to conform to this requirement. If the
>attached changes look all right to you, then I'll install them (or
>something similar) in the coming days.
Much appreciated. Didn't notice/expect a client-side hook running when
committing.
That said, I'd like to +1 the changeset and confirm that the proposed
changes apply cleanly, and yield the desired result. I tested inputs
of the form ^CX,X<text>^C on a temporary private channel – spoilers
are formatted and revealed as intended, and no regressions were
observed. Very nice. Would be a neat addition/fix for the next Erc
release.
Cheers,
FM
Am Sa., 9. März 2024 um 05:43 Uhr schrieb J.P. <jp@neverwas.me>:
>
> Fadi Moukayed <smfadi@gmail.com> writes:
>
> > The only issue I noticed after applying the patches, is that the
> > following warning is emitted on the *Messages* buffer – (Note that I
> > have native compilation enabled):
> >
> >> ⛔ Warning (comp): erc-button.el:532:4: Warning: the function
> >> ‘erc--restore-important-text-props’ is not known to be defined.
> >
> > I assume this is a compilation order issue? Note that this only
> > happens with a clean ELN cache (The following Emacs loads are fine),
> > so not sure how significant it is.
>
> Hm, unless I messed something up (definitely possible), that shouldn't
> happen . For ERC, I typically remove all the lisp/erc/*.elc files after
> every change and before rerunning Make, regardless of whether native
> comp is enabled (though removing native-lisp/30.0.50-deadbeef/*.eln
> isn't usually necessary, AFAICT). Sometimes, though, I also have to
> remove lisp/loaddefs.* and others. In case you weren't aware, there are
> recipes for regenerating various autoloads and Custom business in
> lisp/Makefile, but I usually just delete all stale assets completely.
>
> >>Happy to explain whatever doesn't make sense
> >
> > One question regarding "FIXME use a region instead of point-min/max"
> > in patch #0002, is there a reason why (region-beginning) /
> > (region-end) is indeed not used instead? Just mentioning that because
> > IIRC, point-{min,max} is a range over the entire (narrowed) buffer,
> > including the (buttonized) nick, message text, possible timestamp (if
> > activated) as well. I checked the properties on the whole message line
> > while testing and it doesn't seem to have any negative side-effects,
> > aside from the fact that it operates on more text than it has to – I
> > believe it need only be applied to the message text.
>
> Unfortunately, insertion-hook members lack a means for detecting message
> boundaries unequivocally, although they can obviously keep track of
> their own modifications and make assertions accordingly. So I agree that
> allowing the caller to specify BEG and END in cases where they're
> already known makes sense. For example, if they've already scanned for
> the end of the speaker name to accomplish some other task or happen to
> know the start of the right stamp, it's worth passing that knowledge
> along. But computing a sub-region specially, beforehand, just to call
> this function is likely less efficient (not that you were suggesting
> that). And, of course, accepting BEG/END parameters make it easier to
> protect areas of the exposed buffer from props restoration, if ever
> there's a need.
>
> >> > From 06e008d1de8a85c9e6b9a5a83f5ec5aefeb446c3 Mon Sep 17 00:00:00 2001
> >> > From: "F. Moukayed" <smfadi+emacs@gmail.com>
> >> > Date: Fri, 8 Mar 2024 08:39:03 +0000
> >> > Subject: [PATCH] * lisp/erc/erc-goodies.el: redefine & rework
> >> > `erc-spoilers-face' to indicate revealed text
>
> This is news to me, but apparently there's a Git hook that complains
> about overlong subject lines. After running git-am(1) to apply your
> latest patch, I saw:
>
> Line longer than 78 characters in commit message
> Commit aborted; please see the file CONTRIBUTE
>
> So I adjusted the message to conform to this requirement. If the
> attached changes look all right to you, then I'll install them (or
> something similar) in the coming days.
>
> Thanks,
> J.P.
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <CAG_cVu_gmo0Oc50y7pMTH8Nw_7JkWSMnOD9oZjYWLBiZa-GRfA@mail.gmail.com>
@ 2024-03-09 16:06 ` J.P.
[not found] ` <87bk7n8k5k.fsf@neverwas.me>
1 sibling, 0 replies; 10+ messages in thread
From: J.P. @ 2024-03-09 16:06 UTC (permalink / raw)
To: Fadi Moukayed; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 1270 bytes --]
Fadi Moukayed <smfadi@gmail.com> writes:
> That said, I'd like to +1 the changeset and confirm that the proposed
> changes apply cleanly, and yield the desired result. I tested inputs
> of the form ^CX,X<text>^C on a temporary private channel – spoilers
> are formatted and revealed as intended, and no regressions were
> observed. Very nice. Would be a neat addition/fix for the next Erc
> release.
Really appreciate the thorough testing -- and your patience even more so
because as much as I'd like to put a bow on this, it turns out (sigh)
there's one lingering matter yet unresolved.
Alas, looking more closely at how `erc-controls-propertize' treats
`erc-inverse-face' (crucially, as a modifying toggle [1]), I've quickly
come to rue the day I ever thought to suggest otherwise, especially in
drawing misguided associations with `erc-spoiler-face'. (Indeed, my
quasi-conflating the two was what led us astray to begin with.) So, if
not already clear, I now believe we should just treat `erc-spoiler-face'
as its own concern entirely and not have it inherit from
`erc-inverse-face'. All this to say: yet another revision attached.
Thanks, and apologies for the head fake.
[1] https://modern.ircdocs.horse/formatting#reverse-color
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0000-v2-v3.diff --]
[-- Type: text/x-patch, Size: 10427 bytes --]
From d2ad575e8935981c23846bd54a3eac29b9290f45 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Sat, 9 Mar 2024 07:12:16 -0800
Subject: [PATCH 0/3] *** NOT A PATCH ***
F. Jason Park (2):
[5.6] Leverage inverse-video for erc-inverse-face
. Add new foreground and background face for color code 99
. Don't apply hover props for ^C99,99 because, by definition, the fg and bg
map to different, contrasting colors.
. Use `:inverse-video' face attribute for `erc-inverse-face' to mimic
effect prescribed by https://modern.ircdocs.horse/formatting#reverse-color.
[5.6] Make important text props more resilient in ERC
F. Moukayed (1):
[5.6] Redefine erc-spoiler-face to indicate revealed text
. Have `erc-spoiler-face' inherit from `default' instead of
`erc-inverse-face'.
lisp/erc/erc-button.el | 3 +-
lisp/erc/erc-goodies.el | 39 +++++---
lisp/erc/erc.el | 34 +++++++
test/lisp/erc/erc-goodies-tests.el | 153 ++++++++++++++++++++---------
test/lisp/erc/erc-tests.el | 52 ++++++++++
5 files changed, 223 insertions(+), 58 deletions(-)
Interdiff:
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 212cdbfa9ef..6e9e48e1b81 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -661,11 +661,13 @@ erc-italic-face
:group 'erc-faces)
(defface erc-inverse-face
- '((t :foreground "White" :background "Black"))
+ '((((supports :inverse-video t))
+ :inverse-video t)
+ (t :foreground "White" :background "Black"))
"ERC inverse face."
:group 'erc-faces)
-(defface erc-spoiler-face '((t :inherit erc-inverse-face))
+(defface erc-spoiler-face '((t :inherit default))
"ERC spoiler face."
:group 'erc-faces)
@@ -673,6 +675,16 @@ erc-underline-face
"ERC underline face."
:group 'erc-faces)
+(defface erc-control-default-fg '((t :inherit default))
+ "ERC foreground face for the \"default\" color code."
+ :group 'erc-faces)
+
+(defface erc-control-default-bg '((t :inherit default))
+ "ERC background face for the \"default\" color code."
+ :group 'erc-faces)
+
+;; FIXME rename these to something like `erc-control-color-N-fg',
+;; and deprecate the old names via `define-obsolete-face-alias'.
(defface fg:erc-color-face0 '((t :foreground "White"))
"ERC face."
:group 'erc-faces)
@@ -802,7 +814,7 @@ erc-get-bg-color-face
(intern (concat "bg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :background (aref erc--controls-additional-colors (- n 16))))
- (t (erc-log (format " Wrong color: %s" n)) '(default)))))
+ (t (erc-log (format " Wrong color: %s" n)) 'erc-control-default-fg))))
(defun erc-get-fg-color-face (n)
"Fetches the right face for foreground color N (0-15)."
@@ -818,7 +830,7 @@ erc-get-fg-color-face
(intern (concat "fg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :foreground (aref erc--controls-additional-colors (- n 16))))
- (t (erc-log (format " Wrong color: %s" n)) '(default)))))
+ (t (erc-log (format " Wrong color: %s" n)) 'erc-control-default-bg))))
;;;###autoload(autoload 'erc-irccontrols-mode "erc-goodies" nil t)
(define-erc-module irccontrols nil
@@ -966,7 +978,7 @@ erc-controls-propertize
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (when (and fg bg (equal fg bg))
+ (when (and fg bg (equal fg bg) (not (equal fg "99")))
(add-text-properties from to '( mouse-face erc-spoiler-face
cursor-face erc-spoiler-face)
str)
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index 0ab40808a4a..c8fb0544a72 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -29,19 +29,23 @@
(defun erc-goodies-tests--assert-face (beg end-str present &optional absent)
(setq beg (+ beg (point-min)))
(let ((end (+ beg (1- (length end-str)))))
- (while (and beg (< beg end))
- (let* ((val (get-text-property beg 'font-lock-face))
- (ft (flatten-tree (ensure-list val))))
- (dolist (p (ensure-list present))
- (if (consp p)
- (should (member p val))
- (should (memq p ft))))
- (dolist (a (ensure-list absent))
- (if (consp a)
- (should-not (member a val))
- (should-not (memq a ft))))
- (setq beg (text-property-not-all beg (point-max)
- 'font-lock-face val))))))
+ (ert-info ((format "beg: %S, end-str: %S" beg end-str))
+ (while (and beg (< beg end))
+ (let* ((val (get-text-property beg 'font-lock-face))
+ (ft (flatten-tree (ensure-list val))))
+ (ert-info ((format "looking-at: %S, val: %S"
+ (buffer-substring-no-properties beg end)
+ val))
+ (dolist (p (ensure-list present))
+ (if (consp p)
+ (should (member p val))
+ (should (memq p ft))))
+ (dolist (a (ensure-list absent))
+ (if (consp a)
+ (should-not (member a val))
+ (should-not (memq a ft)))))
+ (setq beg (text-property-not-all beg (point-max)
+ 'font-lock-face val)))))))
;; These are from the "Examples" section of
;; https://modern.ircdocs.horse/formatting.html
@@ -134,30 +138,93 @@ erc-controls-highlight--spoilers
(erc-tests-common-make-server-buf)
(with-current-buffer (erc--open-target "#chan")
(setq-local erc-interpret-mirc-color t)
- (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
- (msg (erc-format-privmessage "bob" m nil t)))
+ (let* ((raw (concat "BEGIN "
+ "\C-c0,0 WhiteOnWhite "
+ "\C-c1,1 BlackOnBlack "
+ "\C-c99,99 Default "
+ "\C-o END"))
+ (msg (erc-format-privmessage "bob" raw nil t)))
(erc-display-message nil nil (current-buffer) msg))
(forward-line -1)
(should (search-forward "<bob> " nil t))
(save-restriction
;; Narrow to EOL or start of right-side stamp.
(narrow-to-region (point) (line-end-position))
- (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
- 'erc-spoiler-face))
- (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
- 'erc-spoiler-face))
- ;; "Spoiler" appears in ERC default face.
+ (save-excursion
+ (search-forward "WhiteOn")
+ (should (eq (get-text-property (point) 'mouse-face)
+ 'erc-spoiler-face))
+ (search-forward "BlackOn")
+ (should (eq (get-text-property (point) 'mouse-face)
+ 'erc-spoiler-face)))
+ ;; Start wtih ERC default face.
(erc-goodies-tests--assert-face
- 0 "Spoiler: " 'erc-default-face
+ 0 "BEGIN " 'erc-default-face
'(fg:erc-color-face0 bg:erc-color-face0))
- ;; "Hello" is masked in all white.
+ ;; Masked in all white.
(erc-goodies-tests--assert-face
- 9 "Hello" '(fg:erc-color-face0 bg:erc-color-face0)
+ 6 "WhiteOnWhite" '(fg:erc-color-face0 bg:erc-color-face0)
'(fg:erc-color-face1 bg:erc-color-face1))
- ;; "World" is masked in all black.
+ ;; Masked in all black.
(erc-goodies-tests--assert-face
- 18 " World" '(fg:erc-color-face1 bg:erc-color-face1 )
- '(fg:erc-color-face0 bg:erc-color-face0))))
+ 20 "BlackOnBlack" '(fg:erc-color-face1 bg:erc-color-face1)
+ '(erc-control-default-fg erc-control-default-bg))
+ ;; Explicit "default" code ignoerd.
+ (erc-goodies-tests--assert-face
+ 34 "Default" '(erc-control-default-fg erc-control-default-bg)
+ '(fg:erc-color-face1 bg:erc-color-face1))
+ (erc-goodies-tests--assert-face
+ 43 "END" 'erc-default-face
+ '(erc-control-default-bg erc-control-default-fg))))
+ (when noninteractive
+ (erc-tests-common-kill-buffers)))
+
+(ert-deftest erc-controls-highlight--inverse ()
+ (should (eq t erc-interpret-controls-p))
+ (erc-tests-common-make-server-buf)
+ (with-current-buffer (erc--open-target "#chan")
+ (setq-local erc-interpret-mirc-color t)
+ (defvar erc-fill-column)
+ (let* ((erc-fill-column 90)
+ (raw (concat "BEGIN "
+ "\C-c3,13 GreenOnPink "
+ "\C-v PinkOnGreen "
+ "\C-c99,99 ReversedDefault "
+ "\C-v NormalDefault "
+ "\C-o END"))
+ (msg (erc-format-privmessage "bob" raw nil t)))
+ (erc-display-message nil nil (current-buffer) msg))
+ (forward-line -1)
+ (should (search-forward "<bob> " nil t))
+ (save-restriction
+ ;; Narrow to EOL or start of right-side stamp.
+ (narrow-to-region (point) (line-end-position))
+ ;; Baseline.
+ (erc-goodies-tests--assert-face
+ 0 "BEGIN " 'erc-default-face
+ '(fg:erc-color-face0 bg:erc-color-face0))
+ ;; Normal fg/bg combo.
+ (erc-goodies-tests--assert-face
+ 6 "GreenOnPink" '(fg:erc-color-face3 bg:erc-color-face13)
+ '(erc-inverse-face))
+ ;; Reverse of previous, so former-bg on former-fg.
+ (erc-goodies-tests--assert-face
+ 19 "PinkOnGreen"
+ '(erc-inverse-face fg:erc-color-face3 bg:erc-color-face13)
+ nil)
+ ;; The inverse of `default' because reverse still in effect.
+ (erc-goodies-tests--assert-face
+ 32 "ReversedDefault" '(erc-inverse-face erc-control-default-fg
+ erc-control-default-bg)
+ '(fg:erc-color-face3 bg:erc-color-face13))
+ (erc-goodies-tests--assert-face
+ 49 "NormalDefault" '(erc-control-default-fg
+ erc-control-default-bg)
+ '(erc-inverse-face fg:erc-color-face1 bg:erc-color-face1))
+ (erc-goodies-tests--assert-face
+ 64 "END" 'erc-default-face
+ '( erc-control-default-fg erc-control-default-bg
+ fg:erc-color-face0 bg:erc-color-face0))))
(when noninteractive
(erc-tests-common-kill-buffers)))
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: 0001-5.6-Leverage-inverse-video-for-erc-inverse-face.patch --]
[-- Type: text/x-patch, Size: 11134 bytes --]
From 2c0b39529cfc9edd6178f4243145688b915d37c6 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:11 -0800
Subject: [PATCH 1/3] [5.6] Leverage inverse-video for erc-inverse-face
* lisp/erc/erc-goodies.el (erc-inverse-face): Prefer the "reversing"
effect of swapping foreground and background colors over affected
intervals. See https://modern.ircdocs.horse/formatting#reverse-color.
(erc-control-default-fg erc-control-default-bg): New faces to allow for
customizing the look of IRC color-code number 99. Ignore the ERC
convention of prefixing control-code-derived faces with "fg:" and
"bg:" because it doesn't comport with modern sensibilities, which
demand identifiers normally be namespaced.
(erc-get-bg-color-face, erc-get-fg-color-face): Don't wrap face in a
list, and use new, dedicated faces.
* test/lisp/erc/erc-goodies-tests.el
(erc-controls-highlight--inverse): Redo, asserting behavior described
in https://modern.ircdocs.horse/formatting#reverse-color.
(erc-controls-highlight--spoilers): New test based on the body of the
old `erc-controls-highlight--inverse', except without shadowing
`erc-insert-modify-hook' with an unrealistic, idealized value. Adjust
expected buffer state to reflect the new role of
`erc-spoiler-face'. (Bug#69597)
---
lisp/erc/erc-goodies.el | 18 +++-
test/lisp/erc/erc-goodies-tests.el | 153 ++++++++++++++++++++---------
2 files changed, 124 insertions(+), 47 deletions(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index 7e30b1060fd..dbf869dafe6 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -661,7 +661,9 @@ erc-italic-face
:group 'erc-faces)
(defface erc-inverse-face
- '((t :foreground "White" :background "Black"))
+ '((((supports :inverse-video t))
+ :inverse-video t)
+ (t :foreground "White" :background "Black"))
"ERC inverse face."
:group 'erc-faces)
@@ -675,6 +677,16 @@ erc-underline-face
"ERC underline face."
:group 'erc-faces)
+(defface erc-control-default-fg '((t :inherit default))
+ "ERC foreground face for the \"default\" color code."
+ :group 'erc-faces)
+
+(defface erc-control-default-bg '((t :inherit default))
+ "ERC background face for the \"default\" color code."
+ :group 'erc-faces)
+
+;; FIXME rename these to something like `erc-control-color-N-fg',
+;; and deprecate the old names via `define-obsolete-face-alias'.
(defface fg:erc-color-face0 '((t :foreground "White"))
"ERC face."
:group 'erc-faces)
@@ -804,7 +816,7 @@ erc-get-bg-color-face
(intern (concat "bg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :background (aref erc--controls-additional-colors (- n 16))))
- (t (erc-log (format " Wrong color: %s" n)) '(default)))))
+ (t (erc-log (format " Wrong color: %s" n)) 'erc-control-default-fg))))
(defun erc-get-fg-color-face (n)
"Fetches the right face for foreground color N (0-15)."
@@ -820,7 +832,7 @@ erc-get-fg-color-face
(intern (concat "fg:erc-color-face" (number-to-string n))))
((< 15 n 99)
(list :foreground (aref erc--controls-additional-colors (- n 16))))
- (t (erc-log (format " Wrong color: %s" n)) '(default)))))
+ (t (erc-log (format " Wrong color: %s" n)) 'erc-control-default-bg))))
;;;###autoload(autoload 'erc-irccontrols-mode "erc-goodies" nil t)
(define-erc-module irccontrols nil
diff --git a/test/lisp/erc/erc-goodies-tests.el b/test/lisp/erc/erc-goodies-tests.el
index 7013ce0c8fc..c8fb0544a72 100644
--- a/test/lisp/erc/erc-goodies-tests.el
+++ b/test/lisp/erc/erc-goodies-tests.el
@@ -29,19 +29,23 @@
(defun erc-goodies-tests--assert-face (beg end-str present &optional absent)
(setq beg (+ beg (point-min)))
(let ((end (+ beg (1- (length end-str)))))
- (while (and beg (< beg end))
- (let* ((val (get-text-property beg 'font-lock-face))
- (ft (flatten-tree (ensure-list val))))
- (dolist (p (ensure-list present))
- (if (consp p)
- (should (member p val))
- (should (memq p ft))))
- (dolist (a (ensure-list absent))
- (if (consp a)
- (should-not (member a val))
- (should-not (memq a ft))))
- (setq beg (text-property-not-all beg (point-max)
- 'font-lock-face val))))))
+ (ert-info ((format "beg: %S, end-str: %S" beg end-str))
+ (while (and beg (< beg end))
+ (let* ((val (get-text-property beg 'font-lock-face))
+ (ft (flatten-tree (ensure-list val))))
+ (ert-info ((format "looking-at: %S, val: %S"
+ (buffer-substring-no-properties beg end)
+ val))
+ (dolist (p (ensure-list present))
+ (if (consp p)
+ (should (member p val))
+ (should (memq p ft))))
+ (dolist (a (ensure-list absent))
+ (if (consp a)
+ (should-not (member a val))
+ (should-not (memq a ft)))))
+ (setq beg (text-property-not-all beg (point-max)
+ 'font-lock-face val)))))))
;; These are from the "Examples" section of
;; https://modern.ircdocs.horse/formatting.html
@@ -129,39 +133,100 @@ erc-controls-highlight--examples
;; Hovering over the redacted area should reveal its underlying text
;; in a high-contrast face.
-(ert-deftest erc-controls-highlight--inverse ()
+(ert-deftest erc-controls-highlight--spoilers ()
(should (eq t erc-interpret-controls-p))
- (let ((erc-insert-modify-hook '(erc-controls-highlight))
- erc-kill-channel-hook erc-kill-server-hook erc-kill-buffer-hook)
- (with-current-buffer (get-buffer-create "#chan")
- (erc-mode)
- (setq-local erc-interpret-mirc-color t)
- (erc--initialize-markers (point) nil)
+ (erc-tests-common-make-server-buf)
+ (with-current-buffer (erc--open-target "#chan")
+ (setq-local erc-interpret-mirc-color t)
+ (let* ((raw (concat "BEGIN "
+ "\C-c0,0 WhiteOnWhite "
+ "\C-c1,1 BlackOnBlack "
+ "\C-c99,99 Default "
+ "\C-o END"))
+ (msg (erc-format-privmessage "bob" raw nil t)))
+ (erc-display-message nil nil (current-buffer) msg))
+ (forward-line -1)
+ (should (search-forward "<bob> " nil t))
+ (save-restriction
+ ;; Narrow to EOL or start of right-side stamp.
+ (narrow-to-region (point) (line-end-position))
+ (save-excursion
+ (search-forward "WhiteOn")
+ (should (eq (get-text-property (point) 'mouse-face)
+ 'erc-spoiler-face))
+ (search-forward "BlackOn")
+ (should (eq (get-text-property (point) 'mouse-face)
+ 'erc-spoiler-face)))
+ ;; Start wtih ERC default face.
+ (erc-goodies-tests--assert-face
+ 0 "BEGIN " 'erc-default-face
+ '(fg:erc-color-face0 bg:erc-color-face0))
+ ;; Masked in all white.
+ (erc-goodies-tests--assert-face
+ 6 "WhiteOnWhite" '(fg:erc-color-face0 bg:erc-color-face0)
+ '(fg:erc-color-face1 bg:erc-color-face1))
+ ;; Masked in all black.
+ (erc-goodies-tests--assert-face
+ 20 "BlackOnBlack" '(fg:erc-color-face1 bg:erc-color-face1)
+ '(erc-control-default-fg erc-control-default-bg))
+ ;; Explicit "default" code ignoerd.
+ (erc-goodies-tests--assert-face
+ 34 "Default" '(erc-control-default-fg erc-control-default-bg)
+ '(fg:erc-color-face1 bg:erc-color-face1))
+ (erc-goodies-tests--assert-face
+ 43 "END" 'erc-default-face
+ '(erc-control-default-bg erc-control-default-fg))))
+ (when noninteractive
+ (erc-tests-common-kill-buffers)))
- (let* ((m "Spoiler: \C-c0,0Hello\C-c1,1World!")
- (msg (erc-format-privmessage "bob" m nil t)))
- (erc-display-message nil nil (current-buffer) msg))
- (forward-line -1)
- (should (search-forward "<bob> " nil t))
- (save-restriction
- (narrow-to-region (point) (pos-eol))
- (should (eq (get-text-property (+ 9 (point)) 'mouse-face)
- 'erc-inverse-face))
- (should (eq (get-text-property (1- (pos-eol)) 'mouse-face)
- 'erc-inverse-face))
- (erc-goodies-tests--assert-face
- 0 "Spoiler: " 'erc-default-face
- '(fg:erc-color-face0 bg:erc-color-face0))
- (erc-goodies-tests--assert-face
- 9 "Hello" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1))
- (erc-goodies-tests--assert-face
- 18 " World" '(erc-spoiler-face)
- '( fg:erc-color-face0 bg:erc-color-face0
- fg:erc-color-face1 bg:erc-color-face1 )))
- (when noninteractive
- (kill-buffer)))))
+(ert-deftest erc-controls-highlight--inverse ()
+ (should (eq t erc-interpret-controls-p))
+ (erc-tests-common-make-server-buf)
+ (with-current-buffer (erc--open-target "#chan")
+ (setq-local erc-interpret-mirc-color t)
+ (defvar erc-fill-column)
+ (let* ((erc-fill-column 90)
+ (raw (concat "BEGIN "
+ "\C-c3,13 GreenOnPink "
+ "\C-v PinkOnGreen "
+ "\C-c99,99 ReversedDefault "
+ "\C-v NormalDefault "
+ "\C-o END"))
+ (msg (erc-format-privmessage "bob" raw nil t)))
+ (erc-display-message nil nil (current-buffer) msg))
+ (forward-line -1)
+ (should (search-forward "<bob> " nil t))
+ (save-restriction
+ ;; Narrow to EOL or start of right-side stamp.
+ (narrow-to-region (point) (line-end-position))
+ ;; Baseline.
+ (erc-goodies-tests--assert-face
+ 0 "BEGIN " 'erc-default-face
+ '(fg:erc-color-face0 bg:erc-color-face0))
+ ;; Normal fg/bg combo.
+ (erc-goodies-tests--assert-face
+ 6 "GreenOnPink" '(fg:erc-color-face3 bg:erc-color-face13)
+ '(erc-inverse-face))
+ ;; Reverse of previous, so former-bg on former-fg.
+ (erc-goodies-tests--assert-face
+ 19 "PinkOnGreen"
+ '(erc-inverse-face fg:erc-color-face3 bg:erc-color-face13)
+ nil)
+ ;; The inverse of `default' because reverse still in effect.
+ (erc-goodies-tests--assert-face
+ 32 "ReversedDefault" '(erc-inverse-face erc-control-default-fg
+ erc-control-default-bg)
+ '(fg:erc-color-face3 bg:erc-color-face13))
+ (erc-goodies-tests--assert-face
+ 49 "NormalDefault" '(erc-control-default-fg
+ erc-control-default-bg)
+ '(erc-inverse-face fg:erc-color-face1 bg:erc-color-face1))
+ (erc-goodies-tests--assert-face
+ 64 "END" 'erc-default-face
+ '( erc-control-default-fg erc-control-default-bg
+ fg:erc-color-face0 bg:erc-color-face0))))
+ (when noninteractive
+ (erc-tests-common-kill-buffers)))
(defvar erc-goodies-tests--motd
;; This is from ergo's MOTD
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: 0002-5.6-Make-important-text-props-more-resilient-in-ERC.patch --]
[-- Type: text/x-patch, Size: 6410 bytes --]
From 7b97bb8fad96fcc2fb48858018bf0e5509a6d741 Mon Sep 17 00:00:00 2001
From: "F. Jason Park" <jp@neverwas.me>
Date: Thu, 7 Mar 2024 21:53:23 -0800
Subject: [PATCH 2/3] [5.6] Make important text props more resilient in ERC
* lisp/erc/erc-button.el (erc-button-remove-old-buttons): Restore
original `mouse-face' values in areas marked as important after
clobbering.
* lisp/erc/erc.el (erc--reserve-important-text-props): New function.
(erc--restore-important-text-props): New function.
* test/lisp/erc/erc-tests.el
(erc--restore-important-text-props): New test.
(Bug#69597)
---
lisp/erc/erc-button.el | 3 ++-
lisp/erc/erc.el | 34 +++++++++++++++++++++++++
test/lisp/erc/erc-tests.el | 52 ++++++++++++++++++++++++++++++++++++++
3 files changed, 88 insertions(+), 1 deletion(-)
diff --git a/lisp/erc/erc-button.el b/lisp/erc/erc-button.el
index 6b78e451b54..4b4930e5bff 100644
--- a/lisp/erc/erc-button.el
+++ b/lisp/erc/erc-button.el
@@ -528,7 +528,8 @@ erc-button-remove-old-buttons
'(erc-callback nil
erc-data nil
mouse-face nil
- keymap nil)))
+ keymap nil))
+ (erc--restore-important-text-props '(mouse-face)))
(defun erc-button-add-button (from to fun nick-p &optional data regexp)
"Create a button between FROM and TO with callback FUN and data DATA.
diff --git a/lisp/erc/erc.el b/lisp/erc/erc.el
index cce3b2508fb..08bc9939b9a 100644
--- a/lisp/erc/erc.el
+++ b/lisp/erc/erc.el
@@ -3532,6 +3532,40 @@ erc--remove-from-prop-value-list
old (get-text-property pos prop object)
end (next-single-property-change pos prop object to)))))
+(defun erc--reserve-important-text-props (beg end plist &optional object)
+ "Record text-property pairs in PLIST as important between BEG and END.
+Also mark the message being inserted as containing these important props
+so modules performing destructive modifications can later restore them.
+Expect to run in a narrowed buffer at message-insertion time."
+ (when erc--msg-props
+ (let ((existing (erc--check-msg-prop 'erc--important-prop-names)))
+ (puthash 'erc--important-prop-names (seq-union existing (map-keys plist))
+ erc--msg-props)))
+ (erc--merge-prop beg end 'erc--important-props plist object))
+
+(defun erc--restore-important-text-props (props &optional beg end)
+ "Restore PROPS where recorded in the accessible portion of the buffer.
+Expect to run in a narrowed buffer at message-insertion time. Limit the
+effect to the region between buffer positions BEG and END, when non-nil.
+
+Callers should be aware that this function fails if the property
+`erc--important-props' has an empty value almost anywhere along the
+affected region. Use the function `erc--remove-from-prop-value-list' to
+ensure that props with empty values are excised completely."
+ (when-let ((registered (erc--check-msg-prop 'erc--important-prop-names))
+ (present (seq-intersection props registered))
+ (b (or beg (point-min)))
+ (e (or end (point-max))))
+ (while-let
+ (((setq b (text-property-not-all b e 'erc--important-props nil)))
+ (val (get-text-property b 'erc--important-props))
+ (q (next-single-property-change b 'erc--important-props nil e)))
+ (while-let ((k (pop val))
+ (v (pop val)))
+ (when (memq k present)
+ (put-text-property b q k v)))
+ (setq b q))))
+
(defvar erc-legacy-invisible-bounds-p nil
"Whether to hide trailing rather than preceding newlines.
Beginning in ERC 5.6, invisibility extends from a message's
diff --git a/test/lisp/erc/erc-tests.el b/test/lisp/erc/erc-tests.el
index 085b063bdb2..6809d9db41d 100644
--- a/test/lisp/erc/erc-tests.el
+++ b/test/lisp/erc/erc-tests.el
@@ -2232,6 +2232,58 @@ erc--remove-from-prop-value-list/many
(when noninteractive
(kill-buffer))))
+(ert-deftest erc--restore-important-text-props ()
+ (erc-mode)
+ (let ((erc--msg-props (map-into '((erc--important-prop-names a))
+ 'hash-table)))
+ (insert (propertize "foo" 'a 'A 'b 'B 'erc--important-props '(a A))
+ " "
+ (propertize "bar" 'c 'C 'a 'A 'b 'B
+ 'erc--important-props '(a A c C)))
+
+ ;; Attempt to restore a and c when only a is registered.
+ (remove-list-of-text-properties (point-min) (point-max) '(a c))
+ (erc--restore-important-text-props '(a c))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 3 (a A b B erc--important-props (a A))
+ 4 7 (a A b B erc--important-props (a A c C)))))
+
+ ;; Add d between 3 and 6.
+ (erc--reserve-important-text-props 3 6 '(d D))
+ (put-text-property 3 6 'd 'D)
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; #1
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))
+ ;; Remove a and d, and attempt to restore d.
+ (remove-list-of-text-properties (point-min) (point-max) '(a d))
+ (erc--restore-important-text-props '(d))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar"
+ 0 2 (b B erc--important-props (a A))
+ 2 3 (d D b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D b B erc--important-props (d D a A c C))
+ 5 7 (b B erc--important-props (a A c C)))))
+
+ ;; Restore a only.
+ (erc--restore-important-text-props '(a))
+ (should (erc-tests-common-equal-with-props
+ (buffer-string)
+ #("foo bar" ; same as #1 above
+ 0 2 (a A b B erc--important-props (a A))
+ 2 3 (d D a A b B erc--important-props (d D a A))
+ 3 4 (d D erc--important-props (d D))
+ 4 5 (d D a A b B erc--important-props (d D a A c C))
+ 5 7 (a A b B erc--important-props (a A c C)))))))
+
(ert-deftest erc--split-string-shell-cmd ()
;; Leading and trailing space
--
2.44.0
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: 0003-5.6-Redefine-erc-spoiler-face-to-indicate-revealed-t.patch --]
[-- Type: text/x-patch, Size: 2344 bytes --]
From d2ad575e8935981c23846bd54a3eac29b9290f45 Mon Sep 17 00:00:00 2001
From: "F. Moukayed" <smfadi+emacs@gmail.com>
Date: Fri, 8 Mar 2024 08:39:03 +0000
Subject: [PATCH 3/3] [5.6] Redefine erc-spoiler-face to indicate revealed text
* lisp/erc/erc-goodies.el (erc-spoiler-face): Redefine role and redo
definition to inherit from `erc-control-default-face'.
(erc-controls-propertize): Include `cursor-face' in the applied hover
properties for spoiler text, and ensure they aren't clobbered by other
built-in modules, like `button'.
(Bug#69597)
Copyright-paperwork-exempt: yes
---
lisp/erc/erc-goodies.el | 21 +++++++++++----------
1 file changed, 11 insertions(+), 10 deletions(-)
diff --git a/lisp/erc/erc-goodies.el b/lisp/erc/erc-goodies.el
index dbf869dafe6..6e9e48e1b81 100644
--- a/lisp/erc/erc-goodies.el
+++ b/lisp/erc/erc-goodies.el
@@ -667,9 +667,7 @@ erc-inverse-face
"ERC inverse face."
:group 'erc-faces)
-(defface erc-spoiler-face
- '((((background light)) :foreground "DimGray" :background "DimGray")
- (((background dark)) :foreground "LightGray" :background "LightGray"))
+(defface erc-spoiler-face '((t :inherit default))
"ERC spoiler face."
:group 'erc-faces)
@@ -980,13 +978,16 @@ erc-controls-propertize
"Prepend properties from IRC control characters between FROM and TO.
If optional argument STR is provided, apply to STR, otherwise prepend properties
to a region in the current buffer."
- (if (and fg bg (equal fg bg))
- (progn
- (setq fg 'erc-spoiler-face
- bg nil)
- (put-text-property from to 'mouse-face 'erc-inverse-face str))
- (when fg (setq fg (erc-get-fg-color-face fg)))
- (when bg (setq bg (erc-get-bg-color-face bg))))
+ (when (and fg bg (equal fg bg) (not (equal fg "99")))
+ (add-text-properties from to '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str)
+ (erc--reserve-important-text-props from to
+ '( mouse-face erc-spoiler-face
+ cursor-face erc-spoiler-face)
+ str))
+ (when fg (setq fg (erc-get-fg-color-face fg)))
+ (when bg (setq bg (erc-get-bg-color-face bg)))
(font-lock-prepend-text-property
from
to
--
2.44.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <87bk7n8k5k.fsf@neverwas.me>
@ 2024-03-09 17:19 ` Fadi Moukayed
[not found] ` <CAG_cVu93JZ=Cx=io3BeYgarXT7FE5Mi5d+Js2Ju89uztgnKnLg@mail.gmail.com>
1 sibling, 0 replies; 10+ messages in thread
From: Fadi Moukayed @ 2024-03-09 17:19 UTC (permalink / raw)
To: J.P.; +Cc: emacs-erc, 69597
[-- Attachment #1: Type: text/plain, Size: 2624 bytes --]
>Really appreciate the thorough testing -- and your patience even more so
>because as much as I'd like to put a bow on this, it turns out (sigh)
>there's one lingering matter yet unresolved.
*Ahem* I apologize for opening this can of worms really. Didn't quite
expect a simple question regarding spoiler rendering to result in this
amount of Erc hackery :)
> [1] https://modern.ircdocs.horse/formatting#reverse-color
Good call. I am aware of this reference (as any IRC tinkerer should
be), and indeed, Erc should handle ^V and ^C99,99 [1], even though
both are "Not universally supported".
I gave the patches another look and did another clean re-apply for an
additional test. All OK (results seen in the attached screenshot).
Implementing ^V using :inverse-video should be okay, although I'm not
sure about the implications on platforms that do not support that (do
any exist? documentation here is sparse, unfortunately). I assume it
will fall back to the hard-coded white-on-black color specification in
that case, which is probably an acceptable compromise.
Cheers,
FM
[1] subtle edge case which shouldn't be formatted as a spoiler, even
though X=Y=99 in ^CX,Y (Again, good catch, thanks for that)
Am Sa., 9. März 2024 um 17:06 Uhr schrieb J.P. <jp@neverwas.me>:
>
> Fadi Moukayed <smfadi@gmail.com> writes:
>
> > That said, I'd like to +1 the changeset and confirm that the proposed
> > changes apply cleanly, and yield the desired result. I tested inputs
> > of the form ^CX,X<text>^C on a temporary private channel – spoilers
> > are formatted and revealed as intended, and no regressions were
> > observed. Very nice. Would be a neat addition/fix for the next Erc
> > release.
>
> Really appreciate the thorough testing -- and your patience even more so
> because as much as I'd like to put a bow on this, it turns out (sigh)
> there's one lingering matter yet unresolved.
>
> Alas, looking more closely at how `erc-controls-propertize' treats
> `erc-inverse-face' (crucially, as a modifying toggle [1]), I've quickly
> come to rue the day I ever thought to suggest otherwise, especially in
> drawing misguided associations with `erc-spoiler-face'. (Indeed, my
> quasi-conflating the two was what led us astray to begin with.) So, if
> not already clear, I now believe we should just treat `erc-spoiler-face'
> as its own concern entirely and not have it inherit from
> `erc-inverse-face'. All this to say: yet another revision attached.
>
> Thanks, and apologies for the head fake.
>
> [1] https://modern.ircdocs.horse/formatting#reverse-color
>
>
[-- Attachment #2: erc-spoilers.png --]
[-- Type: image/png, Size: 13029 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
* bug#69597: 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers
[not found] ` <CAG_cVu93JZ=Cx=io3BeYgarXT7FE5Mi5d+Js2Ju89uztgnKnLg@mail.gmail.com>
@ 2024-03-14 2:17 ` J.P.
0 siblings, 0 replies; 10+ messages in thread
From: J.P. @ 2024-03-14 2:17 UTC (permalink / raw)
To: 69597-done; +Cc: Fadi Moukayed, emacs-erc
Fadi Moukayed <smfadi@gmail.com> writes:
> I gave the patches another look and did another clean re-apply for an
> additional test. All OK (results seen in the attached screenshot).
> Implementing ^V using :inverse-video should be okay, although I'm not
> sure about the implications on platforms that do not support that (do
> any exist? documentation here is sparse, unfortunately). I assume it
> will fall back to the hard-coded white-on-black color specification in
> that case, which is probably an acceptable compromise.
This has been installed as
https://git.savannah.gnu.org/cgit/emacs.git/commit/?id=166c8a98
Thanks and closing.
* * *
A tangentially related note regarding this area of the code base: As
mentioned at least once in code comments, we should probably eventually
begin phasing out the existing face names in favor of ones that abide by
Emacs naming conventions:
- Like all identifiers, they should be properly namespaced, so no
leading "fg:" and "bg:"
- They should _not_ end in "-face" (info "(elisp) Defining Faces")
I don't really have the bandwidth for dealing with this anytime soon,
even though it's a relatively straightforward, mostly mechanical change.
Just thought I'd note it here for the record in case someone reading
this takes a fancy.
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-03-14 2:17 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-06 19:26 29.2; ERC 5.6-git: Add a new customizable variable controlling how Erc displays spoilers Fadi Moukayed
2024-03-07 20:29 ` bug#69597: " J.P.
[not found] ` <87v85xn5uv.fsf@neverwas.me>
2024-03-08 9:07 ` Fadi Moukayed
[not found] ` <CAG_cVu_41w7VufKhJdaWEinQ-fyB22SULmyS0Gx9y+VgjGfYAQ@mail.gmail.com>
2024-03-08 15:05 ` J.P.
[not found] ` <87y1askbmr.fsf@neverwas.me>
2024-03-08 16:47 ` Fadi Moukayed
[not found] ` <CAG_cVu_Jcgk2KRbx7g_dZzsWjE-PQHJwCQuZGSYMV7ZFLZ4qEw@mail.gmail.com>
2024-03-09 4:43 ` J.P.
[not found] ` <87edckc8x2.fsf@neverwas.me>
2024-03-09 10:34 ` Fadi Moukayed
[not found] ` <CAG_cVu_gmo0Oc50y7pMTH8Nw_7JkWSMnOD9oZjYWLBiZa-GRfA@mail.gmail.com>
2024-03-09 16:06 ` J.P.
[not found] ` <87bk7n8k5k.fsf@neverwas.me>
2024-03-09 17:19 ` Fadi Moukayed
[not found] ` <CAG_cVu93JZ=Cx=io3BeYgarXT7FE5Mi5d+Js2Ju89uztgnKnLg@mail.gmail.com>
2024-03-14 2:17 ` J.P.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.