nvim-treesitter / nvim-treesitter/nvim-treesitter-textobjects

C++: `@function.outer` does not work for multiple template declarations

Open
#221 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Tree-sitter Query
Stars
2.8k
Forks
271
Avg merge
8d 8h
Merged PRs (30d)
1

Description

Describe the bug
When a C++ function uses more than one template declaration, all but 1 are ignored in @function.outer queries.

To Reproduce

  1. Create a C++ file with the following (valid) content:
template <class T>
struct A { template <class U> void foo(U); };

template <class T>
template <class U>
void A<T>::foo(U u) {}
  1. Go to the last line
  2. Query @function.outer (delete/select/whatever)
  3. Result: template <class T> is NOT part of the selection, but it should be. It is part of the definition.

Alternatively, on the same file:
2. Go to the line before last: template <class U>
3. Query the @function.outer object
4. Result: only the function declaration itself (without the template lines) gets selected.

Expected behavior
In both cases all 3 last lines should be selected as the @function.outer object.

Output of :checkhealth nvim_treesitter

## Installation
  - WARNING: `tree-sitter` executable not found (parser generator, only needed for :TSInstallFromGrammar, not required for :TSInstall)
  - OK: `node` found v16.15.1 (only needed for :TSInstallFromGrammar)
  - OK: `git` executable found.
  - OK: `cc` executable found. Selected from { vim.NIL, "cc", "gcc", "clang", "cl", "zig" }
    Version: Ubuntu clang version 14.0.5-++20220610081652+4d5dad43b2eb-1~exp1~20220610081739.155
  - OK: Neovim was compiled with tree-sitter runtime ABI version 14 (required >=13). Parsers must be compatible with runtime ABI.

## Parser/Features H L F I J
  - cpp            ✓ ✓ ✓ ✓ ✓ 
  - java           ✓ ✓ . ✓ ✓ 
  - python         ✓ ✓ ✓ ✓ ✓ 
  - c              ✓ ✓ ✓ ✓ ✓ 
  - yaml           ✓ ✓ ✓ ✓ ✓ 
  - json5          ✓ . . . ✓ 
  - jsonc          ✓ ✓ ✓ ✓ ✓ 
  - make           ✓ . . . ✓ 
  - llvm           ✓ . . . . 
  - cmake          ✓ . ✓ . . 
  - proto          ✓ . ✓ . . 
  - json           ✓ ✓ ✓ ✓ . 
  - vim            ✓ ✓ ✓ . ✓ 
  - cuda           ✓ ✓ ✓ ✓ ✓ 
  - javascript     ✓ ✓ ✓ ✓ ✓ 
  - ninja          ✓ . ✓ ✓ . 
  - markdown       ✓ . ✓ . ✓ 
  - lua            ✓ ✓ ✓ ✓ ✓ 
  - toml           ✓ ✓ ✓ ✓ ✓ 
  
  Legend: H[ighlight], L[ocals], F[olds], I[ndents], In[j]ections
         +) multiple parsers found, only one will be used
         x) errors found in the query, try to run :TSUpdate {lang}

Output of nvim --version

NVIM v0.8.0-dev
Build type: Release
LuaJIT 2.1.0-beta3
Compiled by alfaix@ak-pc

Features: +acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM/sysinit.vim"
  fall-back for $VIM: "/usr/local/share/nvim"

Run :checkhealth for more info

Additional context
There can also be more than 2 template declarations per function for nested template structs, though that is much more rare. An example that compiles can be seen on godbolt.

From the looks of it, somewhere right here the parser should be told there may be more than 1 template declaration. I don't really know how to do that, apparently (template_declaration)* is not it.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with queries/cpp/textobjects.scm and reproduce the issue using the C++ snippet in the report. Inspect the @function.outer pattern for template_declaration nodes, then verify that querying either template line selects all three declaration and function lines.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.