emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: master 5c70ff9: New user option 'font-lock-ignore'


From: Eli Zaretskii
Subject: Re: master 5c70ff9: New user option 'font-lock-ignore'
Date: Sat, 02 Apr 2022 09:36:28 +0300

Thanks for developing this feature.

Reading its documentation, I think it should be clarified to be more
useful.  See the questions/comments below:

> +@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?

>                                                            The
> +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.

> 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.

> +@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"?

> +In each buffer, Font Lock keywords that match at least one applicable
> +rule are disabled.

This should be _before_ the list of rules, not after.  And given the
fact that actions of the rules are implicit (i.e. they aren't present
in the rules themselves), I would suggest to call them "conditions",
not "rules".  A rule includes the action, not just the condition for
that action, and those "rules" don't.

> +@smallexample
> +(setq font-lock-ignore
> +      '((prog-mode font-lock-*-face
> +                   (except help-echo))
> +        (emacs-lisp-mode (except ";;;###autoload)")
> +        (whitespace-mode whitespace-empty-at-bob-regexp)
> +        (makefile-mode (except *))))
> +@end smallexample
> +
> +Line by line, this does the following:
> +
> +@enumerate
> +@item
> +In all programming modes, disable all font-lock keywords that apply
> +one of the standard font-lock faces (excluding strings and comments,
> +which are covered by syntactic Font Lock).
> +
> +@item
> +However, keep any keywords that add a @code{help-echo} text property.
> +
> +@item
> +In Emacs Lisp mode, also keep the highlighting of autoload cookies,
> +which would have been excluded by rule 1.
> +
> +@item
> +In @code{whitespace-mode} (a minor mode), don't highlight an empty
> +line at beginning of buffer.

Shouldn't you have "also" in this last description, like you did for
Emacs Lisp mode?

And why doesn't the example show all the possible forms of a "rule",
but just one of them?

> +*** 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?)

> +
> ++++
>  *** New package vtable.el for formatting tabular data.
>  This package allows formatting data using variable-pitch fonts.
>  The resulting tables can display text in variable pitch fonts, text
> diff --git a/lisp/font-lock.el b/lisp/font-lock.el
> index d8a1fe3..8af3c30 100644
> --- a/lisp/font-lock.el
> +++ b/lisp/font-lock.el
> @@ -208,6 +208,7 @@
>  
>  (require 'syntax)
>  (eval-when-compile (require 'cl-lib))
> +(eval-when-compile (require 'subr-x))
>  
>  ;; Define core `font-lock' group.
>  (defgroup font-lock '((jit-lock custom-group))
> @@ -279,6 +280,42 @@ font-lock-maximum-decoration
>                                     (integer :tag "level" 1)))))
>    :group 'font-lock)
>  
> +(defcustom font-lock-ignore nil
> +  "Rules to selectively disable font-lock keywords.
> +This is a list of rule sets of the form
> +
> +  (MODE RULE ...)
> +
> +where:
> +
> + - MODE is a symbol, say a major or minor mode.  The subsequent
> +   rules apply if the current major mode is derived from MODE or
> +   MODE is bound and true as a variable.
> +
> + - Each RULE can be one of the following:
> +   - A symbol, say a face name.  It matches any font-lock keyword
> +     containing the symbol in its definition.  The symbol is
> +     interpreted as a glob pattern; in particular, `*' matches
> +     everything.
> +   - A string.  It matches any font-lock keyword defined by a regexp
> +     that matches the string.
> +   - A form (pred FUNCTION).  It matches if FUNCTION, which is called
> +     with the font-lock keyword as argument, returns non-nil.
> +   - A form (not RULE).  It matches if RULE doesn't.
> +   - A form (and RULE ...).  It matches if all the provided rules
> +     match.
> +   - A form (or RULE ...).  It matches if any of the provided rules
> +     match.
> +   - A form (except RULE ...).  This can be used only at top level or
> +     inside an `or' clause.  It undoes the effect of a previous
> +     matching rule.
> +
> +In each buffer, font lock keywords that match at least one
> +applicable rule are disabled."

Same comments apply to this doc string.

> +  :type '(alist :key-type symbol :value-type sexp)
> +  :group 'font-lock
> +  :version "29.1")
> +
>  (defcustom font-lock-verbose nil
>    "If non-nil, means show status messages for buffer fontification.
>  If a number, only buffers greater than this size have fontification 
> messages."
> @@ -1810,9 +1847,8 @@ font-lock-compile-keywords
>        (error "Font-lock trying to use keywords before setting them up"))
>    (if (eq (car-safe keywords) t)
>        keywords
> -    (setq keywords
> -       (cons t (cons keywords
> -                     (mapcar #'font-lock-compile-keyword keywords))))
> +    (let ((compiled (mapcar #'font-lock-compile-keyword keywords)))
> +      (setq keywords `(t ,keywords ,@(font-lock--filter-keywords compiled))))
>      (if (and (not syntactic-keywords)
>            (let ((beg-function (with-no-warnings syntax-begin-function)))
>              (or (eq beg-function #'beginning-of-defun)
> @@ -1883,6 +1919,50 @@ font-lock-choose-keywords
>       (t
>        (car keywords))))
>  
> +(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.

I'm okay with clarifying the docs myself if you explain enough for me
to understand how to do that.

TIA



reply via email to

[Prev in Thread] Current Thread [Next in Thread]