lewis6991 / nvim-treesitter-context

Show code context
MIT License
44 stars 2 forks source link

"else" is not properly displayed #17

Open jakubgros opened 2 years ago

jakubgros commented 2 years ago

Hello, I have noticed a problem with the plugin when we have such case in C++:

if(caseA)
{
  //...
}
else if(caseB)
{
  //...
}
else
{
  //...
}

When we scroll past the 'else' and we're within its block, the displayed context suggests that we're still in the "else if" block. I have experimented with it a bit and when I change "else" to "else if", the context is displayed properly, so it seems that the "else" is not properly handled by the plugin

My setup: NVIM v0.7.0

  use { -- Shows context when not visible (e.g. class, if, namespace, case in switch)
    'lewis6991/nvim-treesitter-context',
    config = function()
      require'treesitter-context'.setup{
        enable = true, -- Enable this plugin (Can be enabled/disabled later via commands)
        throttle = true, -- Throttles plugin updates (may improve performance)
        max_lines = 0, -- How many lines the window should span. Values <= 0 mean no limit.
        patterns = { -- Match patterns for TS nodes. These get wrapped to match at word boundaries.
          -- For all filetypes
          -- Note that setting an entry here replaces all other patterns for this entry.
          -- By setting the 'default' entry below, you can control which nodes you want to
          -- appear in the context window.
          default = {
            'class',
            'function',
            'method',
          },
          cpp = { -- these values used here are treesitter node names
            'namespace_definition',
            'struct_specifier',
            'access_specifier',
            'class',
            'function',
            'method',
            'for',
            'while',
            'if',
            'switch',
            'case',
          },
        },
      }

      vim.api.nvim_exec(
      [[
        highlight TreesitterContext guibg=#073655 " color of the context popup
      ]], true)
    end
  }
jakubgros commented 2 years ago

I'm attaching treesitter tree for the case below. I'm not the best at interpreting it, but it seems that the "else" is treated as part of "else if", right? I think that "alternative: compound_statement [232, 2] - [236, 3]" should have one indentation level less

  if(caseA)
  {
    //...
    //...
    //...
  }
  else if(caseB)
  {
    //...
    //...
    //...
  }
  else
  {
    //...
    //...
    //...
  }
if_statement [219, 2] - [236, 3]
  condition: condition_clause [219, 4] - [219, 11]
    value: identifier [219, 5] - [219, 10]
  consequence: compound_statement [220, 2] - [224, 3]
    comment [221, 4] - [221, 9]
    comment [222, 4] - [222, 9]
    comment [223, 4] - [223, 9]
  alternative: if_statement [225, 7] - [236, 3]
    condition: condition_clause [225, 9] - [225, 16]
      value: identifier [225, 10] - [225, 15]
    consequence: compound_statement [226, 2] - [230, 3]
      comment [227, 4] - [227, 9]
      comment [228, 4] - [228, 9]
      comment [229, 4] - [229, 9]
    alternative: compound_statement [232, 2] - [236, 3]
      comment [233, 4] - [233, 9]
      comment [234, 4] - [234, 9]
      comment [235, 4] - [235, 9]
syphar commented 2 years ago

I don't fully remember if the matching checks the element name before the :, or after.

But wouldn't adding alternative to your cpp patterns help? It looks like nothing in alternative: compound_statement matches your patterns.

Since this plugin is just walking the tree upwards, having alternative: compound_statement [232, 2] - [236, 3] one indentation level below the else if and below if is actually a good approach :)

binhtran432k commented 2 years ago

This problem may be fix in #3 if I add support for c++ but I'm very busy now for cleaning that PR.