nvim-treesitter / nvim-treesitter

Nvim Treesitter configurations and abstraction layer
Apache License 2.0
10.72k stars 896 forks source link

C/ C++ Auto indenting not working properly inside preprocessor block #5064

Open frobbs opened 1 year ago

frobbs commented 1 year ago

Describe the bug

Hi,

if I type down the following code, the code inside the preprocessor block is not properly indented while typing.

void foo()
{
  {
  }
}

#ifndef MyDef

void bar()
{
{       <=
  }
}

#endif

Same behavior for if, loops and methods. If i mark the block inside "bar" and trigger the indentation, the block is indented properly, I only see the effect while typing.

I tried to break it further down and changed the indents.scm for c to the following:

[
  (compound_statement) 
] @indent.begin

[
  ")"
  "}"
  (statement_identifier)
] @indent.branch

The effect still occurs and I don't see any queries triggering for the "preproc_ifdef" node.

Tree for the example:

function_definition [0, 0] - [4, 1]
  type: primitive_type [0, 0] - [0, 4]
  declarator: function_declarator [0, 5] - [0, 10]
    declarator: identifier [0, 5] - [0, 8]
    parameters: parameter_list [0, 8] - [0, 10]
  body: compound_statement [1, 0] - [4, 1]
    compound_statement [2, 2] - [3, 3]
preproc_ifdef [6, 0] - [14, 6]
  name: identifier [6, 8] - [6, 13]
  function_definition [8, 0] - [12, 1]
    type: primitive_type [8, 0] - [8, 4]
    declarator: function_declarator [8, 5] - [8, 10]
      declarator: identifier [8, 5] - [8, 8]
      parameters: parameter_list [8, 8] - [8, 10]
    body: compound_statement [9, 0] - [12, 1]
      compound_statement [10, 0] - [11, 3]

This is quite painful in c++ working in header files because of the include guard

To Reproduce

create a .c file

write a function inside a ifndef

write a if/ loop or block

Expected behavior

No response

Output of :checkhealth nvim-treesitter

Parser/Features         H L F I J
  - c                   ✓ ✓ ✓ ✓ ✓
  - cpp                 ✓ ✓ ✓ ✓ ✓
  - go                  ✓ ✓ ✓ ✓ ✓
  - lua                 ✓ ✓ ✓ ✓ ✓
  - python              ✓ ✓ ✓ ✓ ✓
  - query               ✓ ✓ ✓ ✓ ✓
  - rust                ✓ ✓ ✓ ✓ ✓
  - tsx                 ✓ ✓ ✓ ✓ ✓
  - typescript          ✓ ✓ ✓ ✓ ✓
  - vim                 ✓ ✓ ✓ . ✓
  - vimdoc              ✓ . . . ✓

Output of nvim --version

NVIM v0.9.1

Additional context

No response

lucario387 commented 1 year ago

I got this when I run gg=G on your code

void foo()
  {
    {
    }
  }

#ifndef MyDef

void bar()
  {
    { 
    }
  }

#endif

Which doesn't seem to be wrong(aside from one extra indentation)

frobbs commented 1 year ago

Thank you for taking a look at this.

As i wrote, I only get the behavior while typing, as you see in the video. This mechanism is triggered by treesitter, isn't it? If I trigger the indentation manually at the end of the video, the code is indented correctly.

https://github.com/nvim-treesitter/nvim-treesitter/assets/133863737/de24e14d-6e55-4bb8-8d29-ab318454c507

I use autoclose plugin for curly braces but it doesn't affect the indentation. I'm not quite sure why you get those extra indentation.

lucario387 commented 1 year ago

I think it's just being over dedented. I'll try to figure out why that's the case

lucario387 commented 1 year ago

The tree errors out, which is weird. This is kindof... expected? Considering that { triggers indentkeys, and when that exists, it's inside an ERROR node, and no longer inside a function definition node (because it's now the ERROR node), leading to one less indent I'll try to see if it's possible to one-off this case