From: Augusto Stoffel <arstoffel@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
Subject: Re: master 5c70ff9: New user option 'font-lock-ignore'
Date: Sat, 02 Apr 2022 13:18:40 +0200 [thread overview]
Message-ID: <87bkxjohrj.fsf@gmail.com> (raw)
In-Reply-To: <83k0c74xd4.fsf@gnu.org> (Eli Zaretskii's message of "Sat, 02 Apr 2022 13:01:59 +0300")
On Sat, 2 Apr 2022 at 13:01, Eli Zaretskii <eliz@gnu.org> wrote:
>> From: Augusto Stoffel <arstoffel@gmail.com>
>> Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
>> Date: Sat, 02 Apr 2022 09:34:25 +0200
>>
>> >> +@example
>> >> +(@var{mode} @var{rule} @dots{})
>> >> +@end example
>> >> +
>> >> +Here, @var{mode} is a symbol, say a major or minor mode.
>> >
>> > Why "say"? Can it usefully be something else? if so, what can it be?
>>
>> This is easiest to explain with code. A rule for a given xyz-mode
>> applies if
>>
>> (or (bound-and-true-p xyz-mode)
>> (derived-mode-p xyz-mode))
>>
>> Do you think it's better to just say “Here, @var{mode} a major or minor
>> mode”? This would be slightly imprecise, because technically 'mode' can
>> be any variable.
>
> If MODE could be any symbol that is bound-and-true-p, does it mean
> that just by defining a variable with a non-nil value will trigger
> such a rule?
That is correct. Of course there could be a conflict if a major mode
name is also bound as a variable. I haven't seen this happen in nature.
However, if you have a better way to test whether a given symbol is a
minor mode and is on, we should definitely use it.
>> >> +subsequent rules apply if the current major mode is derived from
>> >> +@var{mode} or @var{mode} is bound and true as a variable. Each
>> >> +@var{rule} can be one of the following:
>> >> +
>> >> +@table @code
>> >> +@cindex @var{font-lock-ignore} rules
>> >> +@item @var{symbol}
>> >> +A symbol, say a face name, matches any Font Lock keyword containing
>> >> +the symbol in its definition.
>> >
>> > I don't think I understand how can a keyword "contain" a symbol.
>> > Please elaborate or suggest a different text that clarifies this.
>>
>> Okay, as a general remark, this feature has been bolted on the existing
>> font lock mechanism, and it shows. So the user has to interact to some
>> degree with the font-lock internals to make any meaningful use of it.
>>
>> Specifically regarding your question, the user has to be aware that
>> 'font-lock-keywords' is a list where (quoting the docstring):
>>
>> Each element [...] should have one of these forms:
>>
>> MATCHER
>> (MATCHER . SUBEXP)
>> (MATCHER . FACENAME)
>> (MATCHER . HIGHLIGHT)
>> (MATCHER HIGHLIGHT ...)
>> (eval . FORM)
>>
>> where MATCHER can be either the regexp to search for, or the
>> function name to call to make the search (called with one
>>
>> So here I mean that 'symbol' equals the MATCHER, or the FACENAME, or is
>> a member of (flatten-tree FORM), and so on.
>
> It can equal _any_ symbol in those places? Even stuff like 'and'
> etc.? What a strange feature! Why not enable just a test against the
> MATCHER part?
The config example in the manual is not an academic one. I personally
want to disable _most_ font-locking, therefore I use this as my very
first font-lock-ignore rule:
(prog-mode font-lock-*-face)
But I will gladly take some warning fontifications if someone went the
trouble of implementing them. So I'm using this rule as well:
(prog-mode (except help-echo))
Does that catch only fontifications I care about, and not catch any
fontifications I don't care about? Probably not, but it's a good enough
approximation. It achieves something I find pretty good using only 1
very succinct heuristic.
Granted, 'and' is not a meaningful RULE. But it's not disallowed
because there's not point in disallowing it.
>> >> The symbol is interpreted as a glob
>> >> +pattern; in particular, @code{*} matches everything.
>> >
>> > Do you mean shell glob patterns? AFAIK, we don't use them in Emacs
>> > except for shell wildcards, so why are they used here? why not
>> > regexps? And in any case, those patterns need a thorough description,
>> > since we don't use them elsewhere. For example, the way to quote
>> > meta-characters such as '*' must be documented, because it isn't
>> > self-evident.
>>
>> The intention is that the user can write, for instance
>>
>> (setq font-lock-ignore '((prog-mode font-lock-*-face)))
>>
>> and this will be equivalent to
>>
>> (setq font-lock-ignore '((prog-mode (pred (lambda (obj)
>> (and (symbolp obj)
>> (string-match-p
>> "\\`font-lock-.*-face\\'"
>> (symbol-name obj))))))))
>>
>> Do you agree this is a sensible and convenient mini-language? I guess
>> Stefan liked the idea, at least :-).
>
> I understand the intent. I'm saying that we should document this
> "mini-language" in sufficient detail, so that Lisp programmers knew
> how to use it.
Strictly speaking the docstring of 'font-lock-ignore' provides a
complete specification of the mini-language; if not, it's a bug in the
docstring. But we can always expand the examples, of course.
>> >> +@item @var{string}
>> >> +A string matches any font-lock keyword defined by a regexp that
>> >> +matches the string.
>> >
>> > I don't think I understand this sentence. In particular, saying "a
>> > regexp that matches the string" is at least unusual: we usually say it
>> > the other way around: "a string that matches the regexp". And what
>> > does it mean for a keyword to be "defined by a regexp"?
>>
>> Just to make sure we're on the same page, this refers, for instance, to
>> the rule
>>
>> (emacs-lisp-mode ";;;###autoload")
>>
>> which would deactivate the highlighting of autoload cookies.
>>
>> So, we could say "A string matches any font-lock rule which would
>> highlight that string".
>
> What do you mean by "font-lock rule" here?
Yeah, I meant "entry of font-lock-keywords".
>> > And why doesn't the example show all the possible forms of a "rule",
>> > but just one of them?
>>
>> Well, I just wanted to keep true to this being a "@smallexample".
>
> I see no problem with this: adding a couple of lines shouldn't make
> the example too large.
Sounds good.
>> >> +*** New user option 'font-lock-ignore'.
>> >> +This variable provides a mechanism to selectively disable font-lock
>> >> +keywords.
>> >
>> > I don't think it disables keywords, I think it disables
>> > fontifications. (How can one disable a keyword?)
>>
>> Hum, I'm not sure I understand the fine-grained distinction your are
>> making here. font-lock.el speaks of "font lock keywords"; the thing
>> that fontifies variable names with font-lock-variable-face would be a
>> "font lock keyword" in that terminology. I'm just following along the
>> terminology.
>
> That terminology (if this is how you perceive it) is wrong, and I'm
> about to change it to make that more clear. font-lock-keywords are
> not just keywords, they are rules for fontification.
I certainly agree that font-lock.el's use of "font-lock keyword" as a
term for "rules for fontification" is a bit odd. OTOH it's an
established use. Anyway, any changes that make things clearer are
welcome.
> This new feature allows to selectively disable some of those
> fontifications without editing the rules themselves.
That's correct. I see this as an end-user configuration, so providing
the ability to modify the fontifications would probably be going too
far. If someone can come up with an expressive mini-language to modify
fontifications, that might be cool. Other than that, the user can
always modify 'font-lock-keywords' manually.
>> >> +(defun font-lock--match-keyword (rule keyword)
>> >> + "Return non-nil if font-lock KEYWORD matches RULE.
>> >> +See `font-lock-ignore' for the possible rules."
>> >> + (pcase-exhaustive rule
>> >> + ('* t)
>> >> + ((pred symbolp)
>> >> + (let ((regexp (when (string-match-p "[*?]" (symbol-name rule))
>> >> + (wildcard-to-regexp (symbol-name rule)))))
>> >
>> > So "[abcd]" isn't supported by these "glob patterns"? This should be
>> > documented.
>>
>> Ah, okay, I guess we should use the regexp "[][*?]" in that test.
>
> Why not allow a regexp to begin with? Then 2 problems will be solved
> in one blow: (1) the need to change the code, and (2) the need to
> describe what is allowed and what isn't.
So your suggestion is that when RULE is a string, the string is treated
as a regexp and symbol names are matched against it, right?
IMO the current mini-langauge is more useful: the RULE "(defun" can be
used to match the following element of font-lock-keywords found in
emacs-lisp-mode:
```
("(\\(cl-def\\(?:generic\\|m\\(?:acro\\|ethod\\)\\|s\\(?:\\(?:truc\\|ubs\\)t\\)\\|type\\|un\\)\\|def\\(?:a\\(?:dvice\\|lias\\)\\|c\\(?:lass\\|onst\\|ustom\\)\\|face\\|g\\(?:eneric\\|roup\\)\\|ine-\\(?:advice\\|derived-mode\\|g\\(?:\\(?:eneric\\|lobal\\(?:\\(?:ized\\)?-minor\\)\\)-mode\\)\\|inline\\|minor-mode\\|skeleton\\|widget\\)\\|m\\(?:acro\\|ethod\\)\\|subst\\|theme\\|un\\|var\\(?:-local\\|alias\\)?\\)\\|ert-deftest\\)\\_>[ ']*\\(([ ']*\\)?\\(\\(setf\\)[ ]+\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\|\\(?:\\sw\\|\\s_\\|\\\\.\\)+\\)?"
(1 font-lock-keyword-face)
(3
(let
((type
(get
(intern-soft
(match-string 1))
'lisp-define-type)))
(cond
((eq type 'var)
font-lock-variable-name-face)
((eq type 'type)
font-lock-type-face)
((or
(not
(match-string 2))
(and
(match-string 2)
(match-string 4)))
font-lock-function-name-face)))
nil t))
```
>> > I'm okay with clarifying the docs myself if you explain enough for me
>> > to understand how to do that.
>>
>> I guess yes, it would be great if we could have the perspective of a
>> different person incorporated in the documentation, so please go ahead!
>> I'll be glad to provide further clarifications.
>
> Will do, after you reply to this followup message.
Great, thanks!
> Thanks.
next prev parent reply other threads:[~2022-04-02 11:18 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-02 6:36 master 5c70ff9: New user option 'font-lock-ignore' Eli Zaretskii
2022-04-02 7:34 ` Augusto Stoffel
2022-04-02 10:01 ` Eli Zaretskii
2022-04-02 11:18 ` Augusto Stoffel [this message]
2022-04-02 11:58 ` Eli Zaretskii
2022-04-02 12:08 ` Augusto Stoffel
2022-04-02 13:52 ` Eli Zaretskii
2022-04-02 16:25 ` Augusto Stoffel
2022-04-02 16:44 ` Eli Zaretskii
2022-04-02 16:52 ` Augusto Stoffel
2022-04-02 14:06 ` Stefan Monnier
2022-04-02 15:28 ` [External] : " Drew Adams
2022-04-02 16:25 ` Augusto Stoffel
2022-04-02 18:45 ` Drew Adams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87bkxjohrj.fsf@gmail.com \
--to=arstoffel@gmail.com \
--cc=eliz@gnu.org \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.