Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory

Title: Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the after/ Directory

TL;DR

If highlights for your custom tree-sitter parser aren’t applying in Neovim, it’s likely because nvim…


This content originally appeared on DEV Community and was authored by taku25

Title: Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the after/ Directory

custom tree-sitter-unreal-cpp

TL;DR

If highlights for your custom tree-sitter parser aren't applying in Neovim, it's likely because nvim-treesitter isn't loading the highlight queries from your repository. You can solve this by placing your highlight definitions in an after/queries/{filetype}/ directory and loading the parser repository itself as a plugin.

Introduction

To make developing for Unreal Engine in Neovim more comfortable, I created a custom tree-sitter parser, tree-sitter-unreal-cpp, to support UE-specific macros like UCLASS and UPROPERTY.

Creating and testing the parser went smoothly, but when I tried to integrate it with nvim-treesitter, I ran into a problem where the syntax highlighting wouldn't apply at all. In this article, I'll detail the process of figuring out the cause and the final solution.

The Problem: The Parser Works, but Highlights Don't Apply

First, using lazy.nvim, I configured nvim-treesitter to override the default cpp parser with my custom one.

  {
    "nvim-treesitter/nvim-treesitter",
    -- ...
    config = function(_,opts)
      local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
      -- Override the cpp parser config with my custom parser
      parser_config.cpp = {
        install_info = {
          url = "https://github.com/taku25/tree-sitter-unreal-cpp",
          files = {"src/parser.c", "src/scanner.c"},
          branch = "master",
        },
        filetype = "cpp",
      }
      require("nvim-treesitter.configs").setup(opts)
    end,
  },

After this setup, running :TSPlaygroundToggle confirmed that custom nodes like uclass_macro were being parsed correctly. However, no highlights were applied in the editor. Checking with :TSCaptureUnderCursor also showed no highlight groups being detected, which made it difficult to diagnose the problem.

The Cause: nvim-treesitter's Query Loading Specification

After some investigation, I discovered that the problem was caused by a specific behavior of nvim-treesitter.

While nvim-treesitter will build and use a parser from a specified URL in install_info, it does not look for query files (like .scm for highlights) inside your custom repository. Instead, it always uses the query files bundled within its own queries/{filetype}/ directory.

In other words, the queries/highlights.scm file in my tree-sitter-unreal-cpp repository was being completely ignored by nvim-treesitter. That was the root cause of the issue.

The Solution: Extending Queries Using the after Directory

The solution to this behavior is to use Neovim's after directory mechanism. Files placed in an after directory are loaded after the standard configuration files.

This allows us to extend the default cpp queries rather than trying to replace them.

Step 1: Create Query Files in an after Directory Structure

Inside your custom parser repository, create a file at the path after/queries/cpp/highlights.scm. In this file, you should only include the highlight definitions for the new syntax you want to add, such as Unreal Engine macros.

;; extends

; Unreal Engine macros
(uclass_macro "UCLASS" @attribute)
(uproperty_macro "UPROPERTY" @attribute)
; ... other UE-specific definitions

Step 2: Load the Parser Repository as a Plugin

To make Neovim aware of this new after directory, you need to load the tree-sitter-unreal-cpp repository as a standalone plugin in lazy.nvim.

return {
  -- Add your custom parser repository as a plugin
  -- This will add its `after` directory to Neovim's runtime path
  {
    "taku25/tree-sitter-unreal-cpp",
  },

  -- Your existing nvim-treesitter configuration
  {
    "nvim-treesitter/nvim-treesitter",
    -- ...
    config = function(_,opts)
      -- The parser override is still necessary
      local parser_config = require("nvim-treesitter.parsers").get_parser_configs()
      parser_config.cpp = {
        install_info = {
          url = "https://github.com/taku25/tree-sitter-unreal-cpp",
          files = {"src/parser.c", "src/scanner.c"},
          branch = "master",
        },
        filetype = "cpp",
      }
      require("nvim-treesitter.configs").setup(opts)
    end,
  },
}

With this setup, nvim-treesitter first loads the standard C++ highlights, and then our plugin's after/queries/cpp/highlights.scm is loaded, achieving the exact highlighting we want.

Conclusion

If you're facing an issue where highlights aren't applying for your custom tree-sitter parser, the cause is often nvim-treesitter's query loading behavior.

The key to solving this is to place your extension queries in an after/queries/{filetype}/ directory and load your parser repository as a plugin in Neovim. This approach allows you to safely add functionality without breaking existing highlight definitions.

I hope this article helps other developers who run into the same problem.

Have you ever run into similar issues with nvim-treesitter's behavior? If you know of a better approach, please share it in the comments!

P.S. This article was created with the help of Gemini 2.5 Pro (deep research) and GitHub Copilot.


This content originally appeared on DEV Community and was authored by taku25


Print Share Comment Cite Upload Translate Updates
APA

taku25 | Sciencx (2025-09-20T04:43:36+00:00) Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory. Retrieved from https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/

MLA
" » Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory." taku25 | Sciencx - Saturday September 20, 2025, https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/
HARVARD
taku25 | Sciencx Saturday September 20, 2025 » Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory., viewed ,<https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/>
VANCOUVER
taku25 | Sciencx - » Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/
CHICAGO
" » Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory." taku25 | Sciencx - Accessed . https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/
IEEE
" » Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory." taku25 | Sciencx [Online]. Available: https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/. [Accessed: ]
rf:citation
» Custom Parser Highlighting Not Working in nvim-treesitter? The Cause and a Solution Using the `after/` Directory | taku25 | Sciencx | https://www.scien.cx/2025/09/20/custom-parser-highlighting-not-working-in-nvim-treesitter-the-cause-and-a-solution-using-the-after-directory/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.