GNU bug report logs -
#77255
Treesit font-lock override for embed ranges
Previous Next
Reported by: Juri Linkov <juri <at> linkov.net>
Date: Tue, 25 Mar 2025 18:30:02 UTC
Severity: normal
Fixed in version 31.0.50
Done: Juri Linkov <juri <at> linkov.net>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
Caio Juri,
In data mercoledì 26 marzo 2025 08:27:14 Ora standard dell’Europa centrale,
Juri Linkov ha scritto:
> > It looks like we need a new keyword like ':override t' for
> > 'treesit-range-rules' that would override host font-lock rules.
>
> Or maybe not. I managed to do this without any changes in core.
> Also not sure if such functions as treesit-merge-font-lock-feature-list
> and treesit-replace-font-lock-feature-settings could be used here.
>
treesit-replace-font-lock-feature-settings works reliably only if the
replacement is done for rules of the same language. So something like:
#+begin_src emacs-lisp
(setq-local liquid-ts-mode--font-lock-feature-list (treesit-replace-font-lock-
feature-settings
(treesit-font-lock-rules
:language 'html
:override t
:feature 'string
`((attribute
(attribute_name) @_name
(:pred mhtml-ts-mode--not-match @_name)
(quoted_attribute_value) @font-lock-string-face)))
html-ts-mode--treesit-font-lock-settings)
#+end_src
Then:
(defvar mhtml-ts-mode--treesit-font-lock-feature-list
(treesit-merge-font-lock-feature-list
liquid-ts-mode--treesit-font-lock-feature-list
(treesit-merge-font-lock-feature-list
js--treesit-font-lock-feature-list
css--treesit-font-lock-feature-list))
"Settings for `treesit-font-lock-feature-list'.")
However, we could modify treesit-replace-font-lock-feature-settings to check
the language in addition to the feature.
Vincenzo
> The solution below works simply by replacing the html rule with
> another rule that matches only HTML attributes that don't contain
> js code:
>
> #+begin_src emacs-lisp
> (setq-local treesit-range-settings
> (append treesit-range-settings
> (treesit-range-rules
>
> :embed 'javascript
> :host 'html
> :local t
>
> `((attribute
> (attribute_name) @_name
> (:match ,(rx (or "x-data" "x-bind" "x-text"))
> @_name) (quoted_attribute_value
> (attribute_value) @cap))))))
>
> (setq-local treesit-font-lock-settings
> (mapcar (lambda (s)
> (if (and (eq (treesit-query-language
> (treesit-font-lock-setting-query s))
> 'html)
> (eq (treesit-font-lock-setting-feature s)
> 'string))
> (car (treesit-font-lock-rules
>
> :language 'html
> :override t
> :feature 'string
>
> `((attribute
> (attribute_name) @_name
> ;; (:match (not ,(rx (or "x-data"
> "x-bind" "x-text"))) @_name) ;; (:pred (lambda (node)
> ;; (not (string-match-p (rx
> (or "x-data" "x-bind" "x-text")) ;; (treesit-node-text node
> t)))) ;; @_name)
> (:pred mhtml-ts-mode--not-match
> @_name) (quoted_attribute_value) @font-lock-string-face)))) s))
> treesit-font-lock-settings))
> #+end_src
>
> The commented out code shows attempts to use a negated :match
> that is not supported. Also it seems a lambda for :pred is
> also not supported. So needed to add a separate function:
>
> #+begin_src emacs-lisp
> (defun mhtml-ts-mode--not-match (node)
> (not (string-match-p (rx (or "x-data" "x-bind" "x-text"))
> (treesit-node-text node t))))
> #+end_src
>
> Then everything works: all HTML attributes are highlighted
> except those that should highlight js code in them.
This bug report was last modified 92 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.