Subject: Re: bug#72388: 31.0.50; Use tree-sitter-cuda grammar but with tree-sitter-cpp's font-lock/indentation rules

From: Yuan Fu <[email-masked]>
Date: Sun, 19 Jan 2025 22:57:16 -0800

> On Jan 18, 2025, at 4:42 AM, Ergus <[email-masked]> wrote:
> 
> On Fri, Jan 17, 2025 at 05:29:00PM -0800, Yuan Fu wrote:
>> 
>> 
>>> On Jan 17, 2025, at 5:04 PM, Yuan Fu <[email-masked]> wrote:
>>> 
>>> 
>>> 
>>>> On Jan 16, 2025, at 11:35 AM, Ergus <[email-masked]> wrote:
>>>> 
>>>> Hi Yuan:
>>>> 
>>>> It has been a long time since this emails.. But today finally I made my
>>>> serious attempt to make a `cuda-ts-mode`.
>>>> 
>>>> While the treesit-language-remap-alist helped to reuse an important part
>>>> of the code, there were a few issues I needed to manage manually and
>>>> maybe they could be improved somehow:
>>>> 
>>>> 1. The indentation rules still uses the 'cpp prefix, so I had to
>>>> manually tune the code:
>>>> 
>>>> ```
>>>> (defun cuda-ts-mode--simple-indent-rules ()
>>>> (let ((cpp-rules (c-ts-mode--simple-indent-rules
>>>>  'cpp c-ts-mode-indent-style)))
>>>>  `((cuda . ,(alist-get 'cpp cpp-rules)))))
>>>> 
>>>> 
>>>> (setq-local treesit-simple-indent-rules
>>>> (cuda-ts-mode--simple-indent-rules))
>>>> ```
>>>> 
>>>> In order to manage it properly
>>>> 
>>>> 2. I see that font-lock is working, but the fontlock rules check is
>>>> using the cpp parser.
>>>> 
>>>> That's because the c-ts-mode--font-lock-settings still receives cpp as input.
>>>> I am trying to find a way to get it from c++ and then change the
>>>> :language cpp
>>>> with
>>>> :language cuda
>>>> because if I call
>>>> (c-ts-mode--font-lock-settings 'cuda) I obviously get an error.
>>>> 
>>>> Is there some way to go around these in a cleaner way?
>>> 
>>> Thanks Ergus, once you map a language to another, it should be transparent, and you shouldn’t need to change cpp to cuda. It’s most likely a bug somewhere. I’ll fix it.
>>> 
>>> Yuan
>> 
>> Ok, now using c-ts-mode’s font-lock and indentation rules verbatim should work. BTW, you should have
>> 
>> (setq-local treesit-language-remap-alist '((cpp . cuda)))
>> 
>> in cuda-ts-mode’s body.
>> 
>> Yuan
>> 
> 
> Hi Yuan:
> 
> Very thanks for your answer and quick fix ;)
> 
> However when I try this:
> 
> ```
> (define-derived-mode cuda-ts-mode c-ts-base-mode "Cuda"
>  (when (treesit-ready-p 'cuda)
>    (setq-local treesit-primary-parser (treesit-parser-create 'cuda))
>    (setq-local treesit-language-remap-alist '((cpp . cuda)))))
> ```
> 
> `treesit-simple-indent-rules' and `treesit-font-lock-settings' are nil.
> 
> On the other hand:
> 
> If I do instead:
> 
> ```
> (define-derived-mode cuda-ts-mode c++-ts-mode "Cuda" ...
> ```
> 
> Then I have fontlock, but it seems taken from C++ grammar and
> indentation still doesn't work. It actually creates a 'cpp grammar,
> which I think is not desired in this case.
> 
> Indentation doesn't work in this case because:
> 
> ```
> (treesit-node-language (treesit-node-at (point)))
> ```
> 
> returns 'cuda, but `treesit-simple-indent-rules' has 'cpp key; and
> the `treesit-simple-indent' function has:
> 
> ```
> (language (treesit-node-language parent))
> (rules (alist-get language treesit-simple-indent-rules))
> ```
> 
> The code in `c-ts-mode--simple-indent-rules' ends with:
> 
> (pcase mode
>      ('c `((c . ,rules)))
>      ('cpp `((cpp . ,rules))))
> 
> So it can only create 'cpp or 'c keys and `treesit-node-language' uses
> `treesit-parser-language' (which is correct). So I still need to remap
> things manually.
> 
> In font-lock I cannot see in such details because the var
> `treesit-font-lock-settings' is more opaque, but I suppose that there
> may be happening something similar.
> 

Thanks Ergus. I was trying to avoid using the heavy hammer but it seems we have to make it completely transparent. I pushed a change to master. Now when you create a cuda parser using the remapping from cpp, it should completely look and talk like a cpp parser.

Font-lock should work though. It worked for me when I tested it locally.

Yuan