# Regex-Based Syntax Highlighting Had to Go

*A parser that knows exactly where a function ends, not a regex that's guessing — and everything downstream quietly depending on the difference.*

For a long time I thought treesitter was a highlighting upgrade: nicer colors, a keyword that's the right shade of purple instead of whatever regex pattern happened to match it. That's true, but it's not the reason it's load-bearing in my config now. The reason is that everything downstream of it needs a real parse tree, not colors.

Here's the setup, which is smaller than I expected the first time I read it:

```lua
require("nvim-treesitter").setup()
require("nvim-treesitter").install({ "lua", "vim", "python", "java", "c", "cpp", ... })

vim.api.nvim_create_autocmd("FileType", {
  callback = function(ev)
    if pcall(vim.treesitter.start) then
      vim.bo[ev.buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
    end
  end,
})
```

`vim.treesitter.start()` builds an actual syntax tree for the buffer: not "these characters look like a keyword," but "this node is a function\_definition, this one's its body, this one's a parameter." The indentexpr line hands indentation decisions to that tree too, instead of Vim's regex-based indent heuristics guessing from the previous line.

That tree is what everything else queries. My comment in the textobjects plugin spells out the dependency more bluntly than I would've expected myself to write it:

> nvim-treesitter's "main" rewrite moved the textobjects queries out of the core plugin, and nothing else on the runtimepath provides them — so without this, no plugin can ask "where does this function start and end." That includes mini.ai's treesitter spec, which is what wires up `af`/`ic`. Those mappings are dead without this plugin.

So `af` (a function) only works because treesitter-textobjects can answer a structural query, `@function.outer`, and hand back exact start/end coordinates. Same story for `]f` / `[f` jumping between function starts, and `]k` / `[k` for classes, both bound straight to that query system. A regex highlighter has no equivalent answer. It can guess that a line looks like the start of a function; it can't tell you, precisely, where that function's body actually closes.

The sticky-scope plugin makes the same point in scrolling form: it shows the enclosing function or class as you scroll past its opening line, because it's reading the same tree, not re-deriving scope from indentation.
