all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Foreground color opacity
@ 2023-09-11 10:45 Filippo Argiolas
  2023-09-11 12:58 ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-11 10:45 UTC (permalink / raw)
  To: emacs-devel

After the discussion in bug#65418 (Eglot: support clangd
inactiveRegions extension) I wrote a little package starting from João
example code about extending Eglot.

It's little more than an experiment at this point, you can find it at:
https://github.com/fargiolas/clangd-inactive-regions

Long story short clangd introduced a protocol extension in version 17
that signals inactive code (e.g. code under ifdefs) to the editor with
a server notification. Eglot can be easily extended to listen to these
notification and highlight inactive code.

The initial idea was to just use `shadow' face to render inactive
code. But in my opinion a much better solution is to render inactive
code as semi-transparent so that it blends with the background but
still gets syntax highlighting. See the screenshot in github for an
example, other editors have similar UIs for inactive code regions.

My approach so far has been something like this:
- label inactive regions with a dedicated text property
- add a function that runs after fontify-lock-fontify-region-function
(after so we run when we have fortified text with font lock faces)
- inside the fontify function detect face changes in the inactive
region and for each different face encountered apply a new one with
foreground color computed blending current foreground and background

It seems to work so far and I like the result, but I keep thinking
it's overly complicated for something so simple as setting text
opacity. I'm pretty new to emacs lisp, am I missing a face attribute I
can just set in an overlay and get the same result? Wouldn't it make
sense to have something like this at backend level if it doesn't exist
yet?

Thanks,
Filippo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 10:45 Foreground color opacity Filippo Argiolas
@ 2023-09-11 12:58 ` Eli Zaretskii
  2023-09-11 13:09   ` Filippo Argiolas
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-09-11 12:58 UTC (permalink / raw)
  To: Filippo Argiolas; +Cc: emacs-devel

> From: Filippo Argiolas <filippo.argiolas@gmail.com>
> Date: Mon, 11 Sep 2023 12:45:04 +0200
> 
> My approach so far has been something like this:
> - label inactive regions with a dedicated text property
> - add a function that runs after fontify-lock-fontify-region-function
> (after so we run when we have fortified text with font lock faces)
> - inside the fontify function detect face changes in the inactive
> region and for each different face encountered apply a new one with
> foreground color computed blending current foreground and background
> 
> It seems to work so far and I like the result, but I keep thinking
> it's overly complicated for something so simple as setting text
> opacity. I'm pretty new to emacs lisp, am I missing a face attribute I
> can just set in an overlay and get the same result? Wouldn't it make
> sense to have something like this at backend level if it doesn't exist
> yet?

Why not cover the "inactive" portion with an overlay which has the
'face' (or font-lock-face) property that specifies only the opacity?
That is IMO simpler and doesn't need to run any functions after
fontifications.

(Caveat: I didn't actually try this approach, so maybe I'm missing
something.)

Thanks.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 12:58 ` Eli Zaretskii
@ 2023-09-11 13:09   ` Filippo Argiolas
  2023-09-11 14:04     ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-11 13:09 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Mon, Sep 11, 2023 at 2:59 PM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: Filippo Argiolas <filippo.argiolas@gmail.com>
> > Date: Mon, 11 Sep 2023 12:45:04 +0200
> >
> > My approach so far has been something like this:
> > - label inactive regions with a dedicated text property
> > - add a function that runs after fontify-lock-fontify-region-function
> > (after so we run when we have fortified text with font lock faces)
> > - inside the fontify function detect face changes in the inactive
> > region and for each different face encountered apply a new one with
> > foreground color computed blending current foreground and background
> >
> > It seems to work so far and I like the result, but I keep thinking
> > it's overly complicated for something so simple as setting text
> > opacity. I'm pretty new to emacs lisp, am I missing a face attribute I
> > can just set in an overlay and get the same result? Wouldn't it make
> > sense to have something like this at backend level if it doesn't exist
> > yet?
>
> Why not cover the "inactive" portion with an overlay which has the
> 'face' (or font-lock-face) property that specifies only the opacity?
> That is IMO simpler and doesn't need to run any functions after
> fontifications.
>
> (Caveat: I didn't actually try this approach, so maybe I'm missing
> something.)
>
> Thanks.

That would be the perfect solution, but as far as I can tell we don't
have an opacity face attribute, do we?

Filippo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 13:09   ` Filippo Argiolas
@ 2023-09-11 14:04     ` Eli Zaretskii
  2023-09-11 14:58       ` [External] : " Drew Adams
  2023-09-11 16:25       ` Filippo Argiolas
  0 siblings, 2 replies; 12+ messages in thread
From: Eli Zaretskii @ 2023-09-11 14:04 UTC (permalink / raw)
  To: Filippo Argiolas; +Cc: emacs-devel

> From: Filippo Argiolas <filippo.argiolas@gmail.com>
> Date: Mon, 11 Sep 2023 15:09:45 +0200
> Cc: emacs-devel@gnu.org
> 
> > Why not cover the "inactive" portion with an overlay which has the
> > 'face' (or font-lock-face) property that specifies only the opacity?
> > That is IMO simpler and doesn't need to run any functions after
> > fontifications.
> >
> > (Caveat: I didn't actually try this approach, so maybe I'm missing
> > something.)
> >
> > Thanks.
> 
> That would be the perfect solution, but as far as I can tell we don't
> have an opacity face attribute, do we?

Too bad.  (The alpha parameter is what I had in mind , but I see now
that it's only supported for the entire frame, not for a single face.)

Anyway, it sounds inelegant that we need to jump through such hoops to
achieve such a simple effect.  It could even be a problem, if some
Lisp program expects to find the font-lock faces in a buffer, but
instead sees your special faces which replaced them.  E.g., don't we
have features that detect strings and comments in code by looking for
their respective font-lock faces?



^ permalink raw reply	[flat|nested] 12+ messages in thread

* RE: [External] : Re: Foreground color opacity
  2023-09-11 14:04     ` Eli Zaretskii
@ 2023-09-11 14:58       ` Drew Adams
  2023-09-11 16:08         ` Filippo Argiolas
  2023-09-11 16:25       ` Filippo Argiolas
  1 sibling, 1 reply; 12+ messages in thread
From: Drew Adams @ 2023-09-11 14:58 UTC (permalink / raw)
  To: Eli Zaretskii, Filippo Argiolas; +Cc: emacs-devel@gnu.org

> > > Why not cover the "inactive" portion with an overlay which has the
> > > 'face' (or font-lock-face) property that specifies only the opacity?
> > > That is IMO simpler and doesn't need to run any functions after
> > > fontifications.
> > > (Caveat: I didn't actually try this approach, so maybe I'm missing
> > > something.)
> >
> > That would be the perfect solution, but as far as I can tell we don't
> > have an opacity face attribute, do we?
> 
> Too bad.  (The alpha parameter is what I had in mind , but I see now
> that it's only supported for the entire frame, not for a single face.)
> 
> Anyway, it sounds inelegant that we need to jump through such hoops to
> achieve such a simple effect.  It could even be a problem, if some
> Lisp program expects to find the font-lock faces in a buffer, but
> instead sees your special faces which replaced them.  E.g., don't we
> have features that detect strings and comments in code by looking for
> their respective font-lock faces?

I agree that an alpha face attribute would be a good thing.
___

FWIW, in my library `hl-spotlight.el' I shade/highlight the
background over several lines around the cursor - which is
somewhat similar to the feature Filippo described, at least
wrt dimming/highlighting a zone of text.

I use an overlay, similar to what Eli suggested.  Because in
my case the zone is just some contiguous lines I leverage
`hl-line-mode', substituting a different face for the line
background dimming/highlighting.

https://www.emacswiki.org/emacs/HighlightCurrentLine#HlSpotlight
___

`hl-spotlight.el' just uses a face for the overlay, leaving
it up to a user to customize that as needed.

Library `isearch-prop.el' provides similar dimming/lightening
of a zone of text (not necessarily lines).  But it lets you
choose whether to use a particular background color or to dim
or lighten the background by a given factor.  In the latter
case it uses `color-saturate-name' or `color-lighten-name'
from standard library `color.el' to do the dimming/lightening.

https://www.emacswiki.org/emacs/download/isearch-prop.el
___

HTH.




^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [External] : Re: Foreground color opacity
  2023-09-11 14:58       ` [External] : " Drew Adams
@ 2023-09-11 16:08         ` Filippo Argiolas
  0 siblings, 0 replies; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-11 16:08 UTC (permalink / raw)
  To: Drew Adams; +Cc: Eli Zaretskii, emacs-devel@gnu.org

On Mon, Sep 11, 2023 at 4:58 PM Drew Adams <drew.adams@oracle.com> wrote:
> FWIW, in my library `hl-spotlight.el' I shade/highlight the
> background over several lines around the cursor - which is
> somewhat similar to the feature Filippo described, at least
> wrt dimming/highlighting a zone of text.
>
> I use an overlay, similar to what Eli suggested.  Because in
> my case the zone is just some contiguous lines I leverage
> `hl-line-mode', substituting a different face for the line
> background dimming/highlighting.
>
> https://www.emacswiki.org/emacs/HighlightCurrentLine#HlSpotlight
> ___
>
> `hl-spotlight.el' just uses a face for the overlay, leaving
> it up to a user to customize that as needed.
>
> Library `isearch-prop.el' provides similar dimming/lightening
> of a zone of text (not necessarily lines).  But it lets you
> choose whether to use a particular background color or to dim
> or lighten the background by a given factor.  In the latter
> case it uses `color-saturate-name' or `color-lighten-name'
> from standard library `color.el' to do the dimming/lightening.
>
> https://www.emacswiki.org/emacs/download/isearch-prop.el
> ___

Thank you, I will definitely better look into your code with more time later.
At some point I tried using `color-darken-name' but for some reason I
forgot I didn't like it and implemented my own color blending
function. Will look at it again!

Problem is shading the background is kind of easy, with prog modes you
can somewhat safely assume [1] it to be constant on the whole
fontified buffer.
Foreground instead differs for each symbol in a given region so you
need to go over them and apply a different shaded face for each one.

It would be great to offset this job to the backend and just set an
alpha/opacity/whatever attribute in an overlay and let the backend do
the shading.

Cheers,
Filippo

1. kind of expect here to be proved wrong with some funky theme
example that sets different backgrounds for each font lock face



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 14:04     ` Eli Zaretskii
  2023-09-11 14:58       ` [External] : " Drew Adams
@ 2023-09-11 16:25       ` Filippo Argiolas
  2023-09-11 16:56         ` Eli Zaretskii
  1 sibling, 1 reply; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-11 16:25 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Mon, Sep 11, 2023 at 4:04 PM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: Filippo Argiolas <filippo.argiolas@gmail.com>
> > Date: Mon, 11 Sep 2023 15:09:45 +0200
> > Cc: emacs-devel@gnu.org
> >
> > > Why not cover the "inactive" portion with an overlay which has the
> > > 'face' (or font-lock-face) property that specifies only the opacity?
> > > That is IMO simpler and doesn't need to run any functions after
> > > fontifications.
> > >
> > > (Caveat: I didn't actually try this approach, so maybe I'm missing
> > > something.)
> > >
> > > Thanks.
> >
> > That would be the perfect solution, but as far as I can tell we don't
> > have an opacity face attribute, do we?
>
> Too bad.  (The alpha parameter is what I had in mind , but I see now
> that it's only supported for the entire frame, not for a single face.)

Right, I looked into that as well but it seems it's just to set the
whole frame as semitransparent with compositing window managers.

> Anyway, it sounds inelegant that we need to jump through such hoops to
> achieve such a simple effect.  It could even be a problem, if some
> Lisp program expects to find the font-lock faces in a buffer, but
> instead sees your special faces which replaced them.  E.g., don't we
> have features that detect strings and comments in code by looking for
> their respective font-lock faces?

Agreed that's inelegant, unfortunately it's the only way I found so
far without changing the backend, i.e. that works with current Emacs.
Started this thread to see if anyone has a better solution in mind
besides introducing a new opacity/alpha attribute.

Didn't encounter any issue so far with c and c-ts modes but something
like you described could definitely happen if someone relies on font
face to detect symbol type. I'd say that's kind of an unsafe aspect to
rely on. Do you have any example in mind of code doing that so I could
run some tests?

Filippo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 16:25       ` Filippo Argiolas
@ 2023-09-11 16:56         ` Eli Zaretskii
  2023-09-11 19:00           ` Filippo Argiolas
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-09-11 16:56 UTC (permalink / raw)
  To: Filippo Argiolas; +Cc: emacs-devel

> From: Filippo Argiolas <filippo.argiolas@gmail.com>
> Date: Mon, 11 Sep 2023 18:25:50 +0200
> Cc: emacs-devel@gnu.org
> 
> Didn't encounter any issue so far with c and c-ts modes but something
> like you described could definitely happen if someone relies on font
> face to detect symbol type. I'd say that's kind of an unsafe aspect to
> rely on. Do you have any example in mind of code doing that so I could
> run some tests?

One such example is flyspell.el's flyspell-prog-mode.  See
flyspell-prog-text-faces there.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 16:56         ` Eli Zaretskii
@ 2023-09-11 19:00           ` Filippo Argiolas
  2023-09-12  2:21             ` Eli Zaretskii
  0 siblings, 1 reply; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-11 19:00 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Mon, Sep 11, 2023 at 6:57 PM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: Filippo Argiolas <filippo.argiolas@gmail.com>
> > Date: Mon, 11 Sep 2023 18:25:50 +0200
> > Cc: emacs-devel@gnu.org
> >
> > Didn't encounter any issue so far with c and c-ts modes but something
> > like you described could definitely happen if someone relies on font
> > face to detect symbol type. I'd say that's kind of an unsafe aspect to
> > rely on. Do you have any example in mind of code doing that so I could
> > run some tests?
>
> One such example is flyspell.el's flyspell-prog-mode.  See
> flyspell-prog-text-faces there.

Thanks! That should be easily solvable by adding
`font-lock-string-face-clangd-inactive' and the other relevant
inactive face variants to `flyspell-prog-text-faces'.
FWIW with eglot+clangd (and I guess other servers too) inactive code
regions already behave differently because they are not compiled, so
you won't get e.g. any flymake diagnostics or inlay hints, so it could
be a little less of an issue if something else like flyspell in this
case breaks.

Filippo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-11 19:00           ` Filippo Argiolas
@ 2023-09-12  2:21             ` Eli Zaretskii
  2023-09-12  4:55               ` Filippo Argiolas
  0 siblings, 1 reply; 12+ messages in thread
From: Eli Zaretskii @ 2023-09-12  2:21 UTC (permalink / raw)
  To: Filippo Argiolas; +Cc: emacs-devel

> From: Filippo Argiolas <filippo.argiolas@gmail.com>
> Date: Mon, 11 Sep 2023 21:00:35 +0200
> Cc: emacs-devel@gnu.org
> 
> On Mon, Sep 11, 2023 at 6:57 PM Eli Zaretskii <eliz@gnu.org> wrote:
> >
> > > From: Filippo Argiolas <filippo.argiolas@gmail.com>
> > > Date: Mon, 11 Sep 2023 18:25:50 +0200
> > > Cc: emacs-devel@gnu.org
> > >
> > > Didn't encounter any issue so far with c and c-ts modes but something
> > > like you described could definitely happen if someone relies on font
> > > face to detect symbol type. I'd say that's kind of an unsafe aspect to
> > > rely on. Do you have any example in mind of code doing that so I could
> > > run some tests?
> >
> > One such example is flyspell.el's flyspell-prog-mode.  See
> > flyspell-prog-text-faces there.
> 
> Thanks! That should be easily solvable by adding
> `font-lock-string-face-clangd-inactive' and the other relevant
> inactive face variants to `flyspell-prog-text-faces'.
> FWIW with eglot+clangd (and I guess other servers too) inactive code
> regions already behave differently because they are not compiled, so
> you won't get e.g. any flymake diagnostics or inlay hints, so it could
> be a little less of an issue if something else like flyspell in this
> case breaks.

My point is that this technique _will_ break features, and I don't
think it's reasonable to expect each one of them to be fixed
individually.



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-12  2:21             ` Eli Zaretskii
@ 2023-09-12  4:55               ` Filippo Argiolas
  2023-09-12  5:24                 ` Filippo Argiolas
  0 siblings, 1 reply; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-12  4:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Tue, Sep 12, 2023 at 4:21 AM Eli Zaretskii <eliz@gnu.org> wrote:
> > > One such example is flyspell.el's flyspell-prog-mode.  See
> > > flyspell-prog-text-faces there.
> >
> > Thanks! That should be easily solvable by adding
> > `font-lock-string-face-clangd-inactive' and the other relevant
> > inactive face variants to `flyspell-prog-text-faces'.
> > FWIW with eglot+clangd (and I guess other servers too) inactive code
> > regions already behave differently because they are not compiled, so
> > you won't get e.g. any flymake diagnostics or inlay hints, so it could
> > be a little less of an issue if something else like flyspell in this
> > case breaks.
>
> My point is that this technique _will_ break features, and I don't
> think it's reasonable to expect each one of them to be fixed
> individually.

Sure and that's a pretty valid point. Thank you for the insight!
I could experiment a bit more with overlays. Maybe setting an overlay
for each node instead of directly changing the face property. Not sure
if that may impact performance though, need to do some test.

My point was that with eglot there are several features that already
do break within inactive regions, at least with clangd, as the
language server rightfully considers them as dead code. Flymake
diagnostics, symbol highlight, documentation on hover, completion come
to mind but there are probably others.

I'll add a known issues section about this in the readme while I look
for a better solution.

Filippo



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: Foreground color opacity
  2023-09-12  4:55               ` Filippo Argiolas
@ 2023-09-12  5:24                 ` Filippo Argiolas
  0 siblings, 0 replies; 12+ messages in thread
From: Filippo Argiolas @ 2023-09-12  5:24 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: emacs-devel

On Tue, Sep 12, 2023 at 6:55 AM Filippo Argiolas
<filippo.argiolas@gmail.com> wrote:
> > My point is that this technique _will_ break features, and I don't
> > think it's reasonable to expect each one of them to be fixed
> > individually.
>
> Sure and that's a pretty valid point. Thank you for the insight!
> I could experiment a bit more with overlays. Maybe setting an overlay
> for each node instead of directly changing the face property.

FYI, found another potential source of breakage in cc-mode.el
`c-before-change' that looks at the face properties instead of redoing
syntax analysis. Nothing too impactful according to the comments
there, but you're right about font-lock faces being sometimes used to
infer node types.



^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2023-09-12  5:24 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-11 10:45 Foreground color opacity Filippo Argiolas
2023-09-11 12:58 ` Eli Zaretskii
2023-09-11 13:09   ` Filippo Argiolas
2023-09-11 14:04     ` Eli Zaretskii
2023-09-11 14:58       ` [External] : " Drew Adams
2023-09-11 16:08         ` Filippo Argiolas
2023-09-11 16:25       ` Filippo Argiolas
2023-09-11 16:56         ` Eli Zaretskii
2023-09-11 19:00           ` Filippo Argiolas
2023-09-12  2:21             ` Eli Zaretskii
2023-09-12  4:55               ` Filippo Argiolas
2023-09-12  5:24                 ` Filippo Argiolas

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.