Skip to main content

Testing Parsers and Queries

Thorough testing ensures parsers and queries work correctly. This guide covers the testing tools and workflows for nvim-treesitter.

Quick Testing

Run all checks before submitting:
make all
This runs:
  • Lua code formatting and checking
  • Query formatting, linting, and validation
  • Documentation generation
  • Test suite

Testing Parsers

Installation Tests

Test that your parser installs correctly:
:TSInstall <language>
:TSInstallFromGrammar <language>
Both commands should complete without errors.

Health Check

Run Neovim’s health check:
:checkhealth treesitter
This verifies:
  • Parser is installed
  • Parser loads correctly
  • ABI version is supported
  • Queries are valid

Parser Validation Script

Check specific parsers:
./scripts/check-parsers.lua <language>
Or check all installed parsers:
./scripts/check-parsers.lua
The script outputs:
  • ABI version for each parser
  • State count (complexity metric)
  • Any errors loading the parser
All parsers must support the latest ABI version. Older ABI versions may not work with recent Neovim versions.

Manual Parser Testing

Use the tree-sitter CLI to test parsing:
tree-sitter parse path/to/file.ext
This shows:
  • The parsed syntax tree
  • Any parse errors
  • Parse time

Testing Queries

Query Validation

Run the full query test suite:
make query
This executes:
  1. Format check - Ensures queries follow formatting standards
  2. Lint check - Validates captures are correct for Neovim
  3. Pattern check - Verifies patterns match the installed parser

Individual Query Checks

Run checks separately:
# Format queries to standard style
make formatquery

# Validate captures are correct
make lintquery

# Check patterns match parsers
make checkquery

Query Validation Script

Check specific languages:
./scripts/check-queries.lua <language>
Or check all installed queries:
./scripts/check-queries.lua
The script outputs:
  • Parse time for each query file
  • Any query syntax errors
  • Invalid patterns
make checkquery and ./scripts/check-queries.lua require parsers to be installed in the default directory through nvim-treesitter. Install via :TSInstall <language> first.

Interactive Testing

InspectTree

View the syntax tree for the current buffer:
:InspectTree
This opens a window showing:
  • The complete syntax tree
  • Node types and ranges
  • Highlights the text corresponding to the node under cursor
Use this to:
  • Understand parser output
  • Find correct node types for queries
  • Debug why patterns don’t match

EditQuery

Test query patterns interactively:
:EditQuery
This opens a playground where you can:
  • Write query patterns
  • See which parts of the buffer are captured
  • Test different capture groups
  • Iterate quickly on query development

Inspect Highlights

See which highlight groups are applied at cursor:
:Inspect
Shows:
  • Active highlight groups
  • Capture names
  • Priority values
  • Syntax stack
Use this to:
  • Debug highlight conflicts
  • Verify captures work correctly
  • Understand highlight precedence

Testing Highlights

Visual Testing

1

Create test file

Create a file with representative code in your language:
nvim test.<extension>
2

Enable highlighting

Enable tree-sitter highlighting:
:lua vim.treesitter.start()
3

Verify highlighting

Check that:
  • Keywords are highlighted correctly
  • Strings and comments stand out
  • Functions and types are distinguished
  • No obvious missing or incorrect highlights
4

Use :Inspect

Move cursor to different tokens and run:
:Inspect
Verify the capture names are semantically correct.

Highlight Assertions

The test suite supports highlight assertions for automated testing. Create test files in tests/highlights/<language>/:
function test() {
  // <- @keyword.function
  //     ^ @function
  return 42;
  // <- @keyword.return
  //     ^^ @number
}
Run tests:
make tests TESTS=highlights/<language>

Testing Injections

Test multi-language support:
1

Create test file

Create a file with embedded languages (e.g., HTML with JavaScript):
<script>
  console.log("test");
</script>
2

Enable highlighting

:lua vim.treesitter.start()
3

Verify injections

Use :InspectTree to verify:
  • Embedded regions are parsed correctly
  • Syntax tree shows injected language nodes
  • Highlighting works in both languages

Testing Folds

Test code folding:
1

Configure folding

Enable tree-sitter folds:
:set foldmethod=expr
:set foldexpr=v:lua.vim.treesitter.foldexpr()
2

Test folding

  • Use zc to close folds
  • Use zo to open folds
  • Use zM to close all folds
  • Use zR to open all folds
3

Verify fold regions

Check that:
  • Functions fold correctly
  • Blocks fold at appropriate boundaries
  • Nested folds work
  • No unexpected fold regions

Testing Indentation

Tree-sitter indentation is experimental and may have issues.
Test automatic indentation:
1

Enable tree-sitter indentation

:set indentexpr=v:lua.require'nvim-treesitter'.indentexpr()
2

Test indentation

  • Type code and press Enter
  • Use = to re-indent lines
  • Test various language constructs
3

Verify behavior

Check that:
  • Indentation increases after opening blocks
  • Indentation decreases after closing blocks
  • Alignment works for function arguments
  • No unexpected indentation changes

Running the Test Suite

The project includes a test suite using plenary.nvim.

Run all tests

make tests

Run specific tests

make tests TESTS=highlights/<language>
make tests TESTS=parser/<language>

Test output

Tests show:
  • Pass/fail status
  • Error messages for failures
  • Execution time

CI Testing

Required CI Workflows

Parser repositories must have CI workflows:
These workflows verify:
  • Parser compiles on all platforms
  • Query syntax is valid
  • No regressions in parsing

Local CI Simulation

Use the CI install script:
./scripts/ci-install.sh
This sets up dependencies similar to CI environments.

Lua Code Testing

Format Lua code

make formatlua
Uses StyLua to format all Lua code.

Check Lua code

make checklua
Uses lua-language-server to:
  • Type check Lua code
  • Find potential errors
  • Validate API usage

Documentation Testing

Generate documentation

make docs
Updates SUPPORTED_LANGUAGES.md with:
  • List of supported languages
  • Query availability per language
  • Maintainer information
Always run make docs before submitting a PR that adds or modifies parsers.

Common Test Failures

Query linting fails

Error: Invalid captures Solution: Check the valid captures list and use only approved captures for Neovim.

Query checking fails

Error: Pattern doesn’t match Solution:
  • Use :InspectTree to see actual node types
  • Verify parser is installed: :TSInstall <language>
  • Check that pattern syntax is correct

Parser loading fails

Error: ABI version mismatch Solution: Parser must support the latest ABI. Update the parser or contact parser maintainers.

Highlights don’t work

Diagnosis:
  • Run :Inspect at the position
  • Check :InspectTree for node types
  • Run make lintquery for validation
Solution:
  • Ensure capture names match Neovim’s valid captures
  • Verify patterns match actual node types
  • Check highlight groups are defined in your colorscheme

Performance Testing

Query performance

The check script shows parse times:
./scripts/check-queries.lua
Look for:
  • Queries taking > 10ms to parse
  • Significant time differences between similar languages

Parser performance

Use tree-sitter parse to measure:
time tree-sitter parse large-file.ext

Before Submitting

Run the complete test suite:
make all
Ensure:
  • All tests pass
  • No linting errors
  • Documentation is updated
  • New parsers install correctly
  • Queries are validated

Continuous Testing

As a query maintainer:
  1. Monitor parser updates - Parser changes may break queries
  2. Test with real code - Use actual projects in your language
  3. Address issues promptly - Users rely on working queries
  4. Update queries - Keep pace with language evolution

Next Steps