Skip to main content

Overview

Treesitter provides advanced syntax highlighting, indentation, and code understanding through language parsers. It builds an abstract syntax tree (AST) of your code, enabling more accurate and faster highlighting than traditional regex-based approaches. Plugin: nvim-treesitter/nvim-treesitter

Features

  • Superior syntax highlighting based on AST parsing
  • Automatic indentation based on code structure
  • Support for 35+ languages
  • Automatic HTML/JSX tag closing
  • Incremental parsing for performance
  • Context-aware code understanding

Configuration

Treesitter is configured in lua/magictt/plugins/treesitter.lua:
return {
  "nvim-treesitter/nvim-treesitter",
  lazy = false,  -- Load immediately for all files
  build = ":TSUpdate",
  dependencies = {
    "windwp/nvim-ts-autotag",
  },
  config = function()
    local treesitter = require("nvim-treesitter")
    
    -- Install parsers asynchronously
    treesitter.install({ 
      "json",
      "javascript",
      "typescript",
      "tsx",
      "jsx",
      "yaml",
      "html",
      "css",
      "prisma",
      "markdown",
      "markdown_inline",
      "svelte",
      "graphql",
      "bash",
      "lua",
      "vim",
      "dockerfile",
      "gitignore",
      "query",
      "vimdoc",
      "c",
      "astro",
    })

    -- Enable features for supported filetypes
    vim.api.nvim_create_autocmd('FileType', {
      pattern = {
        'json', 'javascript', 'javascriptreact', 'typescript', 'typescriptreact', 'tsx',
        'yaml', 'html', 'css', 'prisma', 'markdown',
        'svelte', 'graphql', 'bash', 'lua', 'vim',
        'dockerfile', 'gitignore', 'c', 'astro'
      },
      callback = function(args)
        -- Enable syntax highlighting
        vim.treesitter.start()
        
        -- Enable treesitter-based indentation
        vim.bo[args.buf].indentexpr = 'v:lua.vim.treesitter.foldexpr()'
      end,
    })

    -- Enable autotag for HTML/JSX
    require("nvim-ts-autotag").setup()
  end,
}

Supported Languages

The Magictt config installs parsers for these languages:

Web Development

  • JavaScript (javascript, jsx)
  • TypeScript (typescript, tsx)
  • HTML (html)
  • CSS (css)
  • Svelte (svelte)
  • Astro (astro)

Data & Config

  • JSON (json)
  • YAML (yaml)
  • GraphQL (graphql)

Backend & Systems

  • Lua (lua)
  • Bash (bash)
  • C (c)
  • Dockerfile (dockerfile)

Documentation

  • Markdown (markdown, markdown_inline)
  • Vim help (vimdoc)

Other

  • Prisma ORM (prisma)
  • Vim script (vim)
  • Git ignore files (gitignore)
  • Treesitter queries (query)

Features in Detail

Syntax Highlighting

Treesitter provides context-aware highlighting:
// Traditional regex might highlight 'return' the same everywhere
// Treesitter understands context:

function calculateReturn() {  // 'return' in name - normal text
  const return_value = 42;    // 'return' in variable - normal text  
  return return_value;        // 'return' keyword - highlighted
}

Automatic Tag Closing

With nvim-ts-autotag, HTML and JSX tags close automatically:
// Type: <div>
// Result: <div>|</div>  (cursor at |)

// Type: <Button>
// Result: <Button>|</Button>

Smart Indentation

Treesitter-based indentation understands code structure:
// Correctly indents based on syntax tree
const obj = {
  nested: {
    deeply: {
      value: true
    }
  }
}

Usage

Treesitter works automatically once configured. No keybindings are needed - it enhances your editing experience invisibly.

Check Parser Status

View installed parsers:
:TSInstallInfo

Update Parsers

Update all installed parsers:
:TSUpdate

Install Additional Parsers

Install a parser not in the config:
:TSInstall python
:TSInstall rust
:TSInstall go

Uninstall Parsers

:TSUninstall python

Check Highlighting

See what Treesitter highlights under cursor:
:Inspect
This shows the syntax groups and highlight information.

Tips and Tricks

Parser Installation

Parsers are installed asynchronously on first load. You might see:
[nvim-treesitter] installing parsers...
This only happens once per parser. Subsequent startups are instant.

Better Than Regex

Traditional syntax highlighting uses regex patterns that can be:
  • Slow on large files
  • Inaccurate with complex syntax
  • Unable to understand context
Treesitter solves all three by parsing the actual syntax tree.

Incremental Parsing

Treesitter only re-parses changed portions of your file, making it fast even in large files.

Language Injection

Treesitter understands embedded languages:
const query = `
  SELECT * FROM users  -- SQL highlighting
  WHERE id = 1
`

const html = `
  <div class="container">  <!-- HTML highlighting -->
    <p>Content</p>
  </div>
`

Auto-tag Configuration

The auto-tag feature works with:
  • HTML files (.html)
  • JSX/TSX files (.jsx, .tsx)
  • Vue files (.vue)
  • Svelte files (.svelte)

Folding with Treesitter

The config sets up Treesitter-based folding:
vim.bo[args.buf].indentexpr = 'v:lua.vim.treesitter.foldexpr()'
This enables code folding based on syntax structure.

Performance

Lazy Loading

The config sets lazy = false to load Treesitter immediately. This ensures:
  • Syntax highlighting works from the first character
  • No delay when opening files
  • Consistent experience across all buffers

File Type Autocmd

Treesitter features are enabled per filetype, so only loaded when needed:
vim.api.nvim_create_autocmd('FileType', {
  pattern = { 'json', 'javascript', ... },
  callback = function(args)
    vim.treesitter.start()
  end,
})

Troubleshooting

Highlighting Looks Wrong

  1. Check if parser is installed:
    :TSInstallInfo
    
  2. Update parsers:
    :TSUpdate
    
  3. Check for conflicts:
    :Inspect
    

Parser Installation Fails

Missing compiler:
# macOS
brew install gcc

# Ubuntu/Debian
sudo apt install build-essential

# Arch
sudo pacman -S base-devel
Network issues:
  • Parsers are downloaded from GitHub
  • Check internet connection
  • Try manual installation: :TSInstall <language>

Auto-tag Not Working

Verify the file type is supported:
:set filetype?
Supported types: html, javascript, javascriptreact, typescript, typescriptreact, vue, svelte

Slow Performance

  • Treesitter is generally fast, but very large files (>10k lines) can be slow
  • Try disabling for specific large files: :TSBufDisable highlight
  • Re-enable with: :TSBufEnable highlight

Indent Issues

If indentation seems wrong:
  1. Check indent expression:
    :set indentexpr?
    
  2. Temporarily use default:
    :set indentexpr=
    
  3. Report issue if it’s a parser bug

Advanced Configuration

Add More Languages

Edit treesitter.lua to add parsers:
treesitter.install({ 
  -- ... existing languages ...
  "python",
  "rust",
  "go",
})
And add to the autocmd pattern:
pattern = {
  -- ... existing patterns ...
  'python', 'rust', 'go'
}

Disable for Specific Files

Create an autocommand:
vim.api.nvim_create_autocmd('BufEnter', {
  pattern = '*.large.js',
  callback = function()
    vim.cmd('TSBufDisable highlight')
  end,
})

Custom Highlight Groups

Treesitter uses standard highlight groups. Customize in your theme:
vim.api.nvim_set_hl(0, '@function', { fg = '#FF5733' })
vim.api.nvim_set_hl(0, '@keyword', { fg = '#33FF57', bold = true })

Dependencies

  • nvim-ts-autotag - Automatic HTML/JSX tag closing
  • C compiler - Required for compiling parsers (gcc, clang)
  • git - For downloading parsers from repositories
  • LSP Setup - Code intelligence and completion
  • Color schemes utilize Treesitter highlighting

Resources

Build docs developers (and LLMs) love