3

I use Emacs with tree sitter for c++ code (c++-ts-mode).
With usual c++-mode I've used this fix for me:

(c-set-offset 'inline-open '0)

but I don't understand how to do it in new c++-ts-mode.

In general I want an indent to be like this:

void sort()
{
    for (int i = 0; i < size - 1; i++) 
    {
        int a;

but now I get this:

void sort()
{
    for (int i = 0; i < size - 1; i++) 
        {
            int a;

2 Answers 2

3

You may want to reuse most of an existing style so that your init.el does not add 100 new lines of indentation rules for every language.

For the C/C++ family, they provide a custom option to add your own function.

In my case, I reused the BSD style and added a few lines on my own.

(defun my-indent-style()
  "Override the built-in BSD indentation style with some additional rules"                                                             
  `(;; Here are your custom rules
    ((node-is ")") parent-bol 0)                                                                                                         
    ((match nil "argument_list" nil 1 1) parent-bol c-ts-mode-indent-offset)                                                                                   
    ((parent-is "argument_list") prev-sibling 0)                                                                                         
    ((match nil "parameter_list" nil 1 1) parent-bol c-ts-mode-indent-offset)
    ((parent-is "parameter_list") prev-sibling 0) 

    ;; Append here the indent style you want as base                                                                                       
   ,@(alist-get 'bsd (c-ts-mode--indent-styles 'cpp))))                                                                                                                                                                                                                  

(use-package c-ts-mode                                                                                                                       
 :if (treesit-language-available-p 'c)                                                                                                
 :custom                                                                                                                              
 (c-ts-mode-indent-offset 4)                                                                                                          
 (c-ts-mode-indent-style #'my-indent-style)                                                                                           
 :init                                                                                                                                          
 ;; Remap the standard C/C++ modes                                                                                                        
 (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))                                                                          
 (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))                                                                      
 (add-to-list 'major-mode-remap-alist '(c-or-c++-mode . c-or-c++-ts-mode)))
2
  • Unfortunately, I haven't found a decent description of how "node-is" etc work. Rule order also seems to be important.
    – ahnkle
    Commented Oct 12, 2023 at 9:15
  • On my hand I followed this guide, which was really helpful : git.savannah.gnu.org/cgit/emacs.git/tree/admin/notes/… As for the order you can see this list as a bunch of if/else if/else statements, so if one of the first rules matches it will not process the following. Be sure to put your narrow rules first
    – Charles G
    Commented Oct 13, 2023 at 6:43
2

In general indent is controlled by treesit-simple-indent-rules variable.
Which (in new c++-ts-mode) is controlled by c-ts-mode--indent-styles function.

I had to redefine c-ts-mode--indent-styles adding those lines:

  ...
  ((parent-is "binary_expression") parent 0)

+ ((query "(do_statement body: (compound_statement) @indent)") parent-bol 0)
+ ((query "(do_statement \"while\" @indent)") parent-bol 0)
+ ((query "(if_statement consequence: (compound_statement) @indent)") parent-bol 0)
+ ((query "(for_statement body: (compound_statement) @indent)") parent-bol 0)

  ((query "(for_statement initializer: (_) @indent)") parent-bol 5)
  ...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.