No. I defined a function for "treesit-language-at", which works correctly without tree-sitter-phodoc parser (the version without phpdoc is here https:// github.com/vpxyz/php-ts-mode) I find two problems: 1. treesit-range-rules does not reset the variable "local" at the end of pcase as it does with "host", "embed" and "offset". If there is a parser with the :local attribute, all parsers defined after it are marked as :local Without fix: treesit-range-settings is a variable defined in ‘~/Projects/Emacs/php-ts-mode/ treesit.el’. Its value is ((# phpdoc t nil) (# html t nil) (# javascript t (1 . -1)) (# css t (1 . -1))) Local in buffer index4.php; global value is nil with fix: treesit-range-settings is a variable defined in ‘~/Projects/Emacs/php-ts-mode/ treesit.el’. Its value is ((# phpdoc t nil) (# html nil nil) (# javascript nil (1 . -1)) (# css nil (1 . -1))) Local in buffer index4.php; global value is nil 2. treesit-font-lock-fontify-region: the variable "global-parser" is set with all parsers defined, including local parsers. As result the root-nodes variable, without fix are ("document node" is a phpdoc node): root-nodes (# # # # # # #) with fix: root-nodes (# # # # # #) you can see the difference in the attached screenshots. The patch I wrote is not a solution (it's trivial) . I think there are other "moving parts" to take into account. Thanks. In data sabato 27 gennaio 2024 05:32:02 CET, Yuan Fu ha scritto: > > On Jan 11, 2024, at 3:15 AM, Vincenzo Pupillo wrote: > > > > Hi, > > in the php-ts-mode I am writing, I am trying to use the tree-sitter-phpdoc > > parser (I had tried before but without success, and I currently use a > > font block based on regular expressions). > > tree-sitter-phpdoc requires a single doc block (a single /** */ doc block > > and nothing else, no /* */ or #). I wrote these range rules: > > (setq-local treesit-range-settings > > > > (treesit-range-rules > > > > :embed 'phpdoc > > :host 'php > > :local t > > > > '(((comment) @cap > > > > (:match "/\\*\\*" @cap))) > > > > :embed 'html > > :host 'php > > > > '((program (text) @cap) > > > > (text_interpolation (text) @cap)) > > > > :embed 'javascript > > :host 'html > > :offset '(1 . -1) > > > > '((script_element > > > > (start_tag (tag_name)) > > (raw_text) @cap)) > > > > :embed 'css > > :host 'html > > :offset '(1 . -1) > > > > '((style_element > > > > (start_tag (tag_name)) > > (raw_text) @cap)))) > > > > With html, js and css it works fine. With phpdoc I tried with or without > > :local. Without :local the parse intervals are all null. Without :local > > on the other hand they are correct. With this simple php snippet: > > > > > /** > > * Test class > > * @author v > > */ > > class Test { > > > > /** @see http://example.com the lib */ > > function test() { > > > > echo "prova"; > > > > } > > > > } > > > > Without :local the field rules are: > > ((# ((1 . 1) (8 . 64) (82 . 120))) (# > parser for html> ((1 . 1) (1 . 2))) (# ((1 . 1))) > > (# ((1 . 1))) (# > > nil)) > > > > With :local the result is: > > ((# nil) (# nil) > > (# nil) (# nil) > > (# nil)) > > > > > > With :local the treesit-language-at breaks, and js or css rules > > are also applied to php code :-( > > > > I tried tracking the node location sent from the parser to the > > font-lock-rules I wrote for phpdoc, with :local the result is: > > > > phpdoc-block node-start= 8 node-end= 64 start= 1 end= 166 > > phpdoc-block node-start= 82 node-end= 120 start= 1 end= 166 > > phpdoc-block node-start= 1 node-end= 166 start= 1 end= 166 > > > > the first two are right, the last one is not. > > > > Any idea? > > Tested with: > > GNU Emacs 30.0.50 (build 3, x86_64-pc-linux-gnu, GTK+ Version 3.24.39, > > cairo version 1.18.0) of 2024-01-11 > > > > > > Thanks > > > > p.s. the function I wrote to get the ranges is: > > (defun php-ts-mode--get-parser-ranges () > > > > "Return the ranges covered by the parsers. > > > > `php-ts-mode' use 5 parsers, this function returns, for the > > current buffer, the ranges covered by each parser. > > Usefull for debugging." > > > > (let ((ranges)) > > > > (if (not (treesit-parser-list)) > > > > (message "At least one parser must be initialized")) > > > > (cl-loop > > > > for parser in (treesit-parser-list) > > do (push (list parser (treesit-parser-included-ranges parser)) ranges) > > finally return ranges))) > > IIUC your problem is that treesit-language-at doesn’t work, right? Have you > assigned treesit-language-at-function? People often assume > treesit-language-at works automatically when they define > treesit-range-rules. But you actually need to define > treesit-language-at-function. > > Yuan