I'm using coc-clangd and nvim-treesitter in NeoVim, and I have the following requirements.

  1. set the global variable identifiers to bold
  2. set the virtual function identifiers to italic
  3. set the macro identifiers to a specific color

It seems nvim-treesitter's classification of identifer was not detailed enough. And I want the rules should only be adopted in C++.

1 Answer 1


Yes, the C++ Treesitter parser does not check for macro identifiers, but it cannot identify virtual function identifiers and global variable identifiers. Treesitter creates only concrete syntax trees. You must use your LSP. I’m sorry, I do not know coc-clangd, so I will use the built-in LSP in nvim. Your procedure should be similar.

To set a custom highlighting group, use vim.api.nvim_set_hl({ns_id}, {name}, {val}) (for more, check :help nvim_set_hl). To get the name of the highlighting group, use :Inspect (for more, check :help Inspect). This command will show you the set of highlighting groups for the token under the cursor.

So if I call :Inspect at virtual bool isA();, I will see:

  - @function.method.cpp links to Function cpp                                                           
Semantic Tokens                                                                                          
  - @lsp.type.method.cpp links to Function priority: 125                                                 
  - @lsp.mod.classScope.cpp links to @lsp priority: 126                                                  
  - @lsp.mod.declaration.cpp links to @lsp priority: 126                                                 
  - @lsp.mod.virtual.cpp priority: 126                                                                   
  - @lsp.typemod.method.classScope.cpp links to @lsp priority: 127                                       
  - @lsp.typemod.method.declaration.cpp links to @lsp priority: 127                                      
  - @lsp.typemod.method.virtual.cpp links to @lsp priority: 127

Here you can choose @lsp.mod.virtual.cpp or @lsp.typemod.method.virtual.cpp. For example, I will choose the first one, which is more generic. Now set the highlighting group to italic.

vim.api.nvim_set_hl(0, '@lsp.mod.virtual.cpp', { italic = true })

Do the same for macro identifiers and global variable identifiers, but be careful with global variable identifiers. If you choose more general approach, you cannot unset your bold text. So if you use:

vim.api.nvim_set_hl(0, '@lsp.typemod.variable.cpp', { bold = true })
vim.api.nvim_set_hl(0, '@lsp.typemod.namespace.globalScope.cpp', { bold = false })

You will have bold global variable identifiers but also all global namespace identifiers.

Highlighting groups that end with cpp mean this highlighting group is applied only for the cpp filetype. If you do not have this option, you can use an auto command.

So for me, the final solution will look like:

vim.api.nvim_set_hl(0, '@lsp.mod.virtual.cpp', { italic = true })
vim.api.nvim_set_hl(0, '@lsp.type.macro.cpp', { fg = "red" })
vim.api.nvim_set_hl(0, '@lsp.typemod.variable.globalScope.cpp', { bold = true })

And the result will look like:


You can notice that cout is also bold. This is expected behavior, but if you do not want this, I’m sorry, I do not know how to change it.

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.