emacs-devel
[Top][All Lists]
Advanced

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

Re: tree-sitter user rules.


From: Yuan Fu
Subject: Re: tree-sitter user rules.
Date: Thu, 30 Jan 2025 21:37:16 -0800


> On Jan 27, 2025, at 7:20 PM, Ergus <spacibba@aol.com> wrote:
> 
> Hi Yuan:
> 
> On January 28, 2025 2:51:00 AM GMT+01:00, Yuan Fu <casouri@gmail.com> wrote:
>> 
>> 
>>> On Jan 17, 2025, at 10:52 AM, Ergus <spacibba@aol.com> wrote:
>>> 
>>> Hi:
>>> 
>>> I have been hacking a bit treesitter to add a few custom indentation
>>> rules that behave "weird" in my system.
>>> 
>>> At the end I have this workaround, but I am wondering if we could add
>>> something less hacky in order to allow the user insert some rules over
>>> existing styles:
>>> 
>>> ```
>>> (defun my/treesit-simple-indent (oldfun node parent bol)
>>>   "Allow indent with custom rules without hacks in the predefined rules
>>> 
>>> It is possible to change the treesit-indent-function BUT the python mode
>>> breaks because there is some hacky condition assigning the indentation
>>> function in the tree-sitter library."
>>>   (or (when-let* ((rules (alist-get (treesit-node-language parent)
>>>     my/treesit-indent-rules))
>>>   (treesit-simple-indent-rules my/treesit-indent-rules)
>>>   (result (funcall oldfun node parent bol))
>>>   ((or (car result)
>>> (cdr result))))
>>> result)
>>> (funcall oldfun node parent bol)))
>>> 
>>> ;; Add an advise to check my indentations before the default ones.
>>> ;; I cannot use another function and set it to treesit-indent-function
>>> ;; because some code in tressitter.el apparently checks that
>>> ;; (eq treesit-indent-function '#treesit-simple-indent)
>>> (advice-add 'treesit-simple-indent :around #'my/treesit-simple-indent)
>>> 
>>> ;; The for example for rust:
>>> (defun my/rust-ts-mode-hook ()
>>>   "Hook to improve indentation in rust mode"
>>>   (setq-local tab-width 4)
>>> 
>>>   (setq-local my/treesit-indent-rules
>>> `((rust . (((and (parent-is "function_item")
>>> (node-is "block")) parent-bol 0))))))
>>> (add-hook 'rust-ts-mode-hook #'my/rust-ts-mode-hook)
>>> 
>>> ```
>>> 
>>> I propose to add a variable equivalent to my/treesit-indent-rules and
>>> make treesit-simple-indent try to get a match from there before, else
>>> rely on treesit-simple-indent-rules
>>> 
>>> WDYT?
>> 
>> Hey Ergus, have you considered this:
>> 
>> (setq-local treesit-simple-indent-rules
>>          `((rust . ,(append (your rules)
>>                          (alist-get ‘rust treesit-simple-indent-rules)))))
>> 
>> In the major mode hook? That’s the way of customization I had in mind when 
>> writing the indentation facility.
> 
> Yes I actually use that until now. But it becomes cumbersome in some cases 
> like when working with different projects and I need to add different rules 
> in the dir_locals file for each of them.

Ah, I haven’t thought about that before.

> 
>> I do agree that we can have a function to simplify it. Similar to 
>> treesit-add-font-lock-rules, we can add a treesit-add-simple-indent-rules, 
>> that also hands adding rules before/after the existing rules, or a certain 
>> rule.
>> 
>> Yuan
> 
> A variable will be simpler to manage and keep clean the original rules. 
> Separated for user custom ones.
> 
> Using functions for this is more complex compared with setting a custom 
> variable. And won't take advantages of the defcustom facility. But that's 
> just my opinion ;)

Ok, I end up adding both. Now there’s treesit-simple-indent-override-rules that 
overrides regular rules. You can also use treesit-add-simple-indent-rules to do 
more complex customization on the regular rules.

I didn’t define it as a custom option though, just a local variable.

Yuan


reply via email to

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