Problem: when attach() runs from a FileType autocmd, did_filetype() = 1
causes vim.filetype.match to return nil for function-handled extensions
(.lua, .py, .sh, etc). ensure_cache correctly schedules a deferred
invalidate_cache via vim.schedule, but invalidate_cache only sets
tick = -1 without forcing a redraw. Since the buffer is static, Neovim
never triggers the decoration provider again, so the reparse with
did_filetype() = 0 never happens until the user interacts.
Solution: call vim.cmd('redraw') after invalidate_cache in the deferred
callback. This forces the decoration provider to re-enter on_buf, which
sees the invalidated tick, reparses with did_filetype() = 0, and applies
language-specific treesitter highlighting.