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

From: Ergus <[email-masked]>
Date: Sat, 18 Jan 2025 13:42:47 +0100

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.