Specifically proposing developing a tree-sitter grammer for cooklang, not based on existing work, except for the official validation tests.
6.9 KiB
Problem Statement
This machine's Neovim config (~/.config/nvim, tracked in the dot dotfiles repo, using lazy.nvim + nvim-treesitter) has no Cooklang support today: no filetype detection for .cook files, and no highlighting.
Once the standalone tree-sitter-cooklang grammar (see the companion spec) exists, this repo's Neovim config needs to be wired up to actually use it.
Solution
Add a new lua/plugins/filetypes.lua to the Neovim config. It registers .cook as filetype cooklang via vim.filetype.add, and extends the existing nvim-treesitter plugin spec (currently defined in ui.lua) — via lazy.nvim's spec-merging for a single plugin across multiple files — to register the cooklang parser's install_info and add it to ensure_installed.
This lets nvim-treesitter's existing eager-load behavior and dot setup nvim's existing headless bootstrap (Lazy! restore, which already drives ensure_installed as a side effect) pick up, build, and attach the new parser with no changes to either of those existing mechanisms.
User Stories
- As the machine owner, I want opening a
.cookfile to be recognized as filetypecooklangautomatically, so I don't have to set it by hand. - As the machine owner, I want that filetype to get tree-sitter-based syntax highlighting from the from-scratch grammar, so recipes are visually readable.
- As the machine owner, I want the custom-parser registration to live in its own file (
filetypes.lua) rather than insideui.lua's generic colorscheme/treesitter block, so a one-off, filetype-specific hack stays separated from generic editor infrastructure, and any future custom filetype has an established home to go in. - As the machine owner, I want
filetypes.luato hold both the filetype-detection call and the parser registration together, so "everything about custom filetypes" is one discoverable file, rather than split between a nativeftdetect/file and alua/plugins/file. - As the machine owner, I want this to piggyback on the existing
dot setup nvimheadless bootstrap without requiring any change to that command, so a fresh-machine setup keeps working for this new filetype the same way it already does for every other pinned plugin/parser. - As the machine owner, I want no folding or indentation behavior changes for
.cookfiles, so this change stays scoped to highlighting only, matching what was actually asked for. - As the machine owner, I want to verify the result by opening a real
.cookfile and checking the highlighting by eye (plus:InspectTree/:Inspectfor node-level checks), so I don't have to stand up new automated test infrastructure for one query file in a personal config that has no existing automated-test story of its own.
Implementation Decisions
- New file:
~/.config/nvim/lua/plugins/filetypes.lua. No wiring changes needed elsewhere —lazy.nvim's existing{ import = "plugins" }spec (ininit.lua/plugin.lua) already imports every file underlua/plugins/. - Top of the file: a plain
vim.filetype.add({ extension = { cook = "cooklang" } })call, executed as a side effect when the module is required (every file underlua/plugins/is required unconditionally as part oflazy.nvim's spec collection, so this runs at startup regardless of any plugin's load timing). Deliberately not using the nativeftdetect/runtime-directory convention, to keep all custom-filetype logic in the one file. - Below that: the file's returned plugin-spec table contains one entry for
"nvim-treesitter/nvim-treesitter"using anoptsfunction that merges into the plugin's existing options (already defined inui.lua).lazy.nvimsupports multiple partial specs for the same plugin across different imported files and merges them — this avoids touching or duplicating the existing spec inui.lua. - That
optsfunction registers thecooklangparser viarequire("nvim-treesitter.parsers").get_parser_configs()(settinginstall_info.url/branch/files, pointing at the companiontree-sitter-cooklangspec's eventual repo, andfiletype = "cooklang"), and appends"cooklang"to the existingensure_installedlist. install_info.url/branchare placeholders until the companion grammar repo actually exists and is hosted somewhere (see companion spec — hosting is explicitly out of scope there too). Filling these in is a mechanical last step once that repo exists, not a design decision this spec needs to resolve.- No changes needed to
ui.luaitself, nor to thedot setup nvimcommand or its spec:nvim-treesitteralready loads eagerly (no lazy-load trigger), anddot setup nvim's headlessLazy! restorealready drivesensure_installedas a side effect of that eager load (per the existingdot-setup-nvimspec). The newcooklangentry is automatically picked up by both an interactive launch and a headlessdot setup nvimrun with zero code changes to that command. - No
after/ftplugin/cooklang.luaor other filetype-specific settings (e.g. noconcealleveloverride, unlikemarkdown.lua's) — not requested; scope is highlighting only.
Testing Decisions
- Manual verification only: open a sample
.cookfile, confirm the expected highlight groups render, use:InspectTree/:Inspectfor node-level spot checks. - No automated test is added to this Neovim config for this change — the config has no existing automated-test story of its own (unlike the
dotCLI, which has realfishtapecoverage). Parsing correctness itself is covered by the companion grammar spec'scanonical.yaml-derived corpus, which is the appropriate seam for that concern — this integration is a downstream consumer of it, not a place to re-test it. - The existing
dot setup nvimfishtapecoverage (fake-nvim-binary pattern) is not extended for this change. It already only asserts "every pinned plugin has a directory," not individual tree-sitter parser success — an intentional, pre-existing scope boundary from thedot-setup-nvimspec that this integration doesn't change.
Out of Scope
- Building the grammar itself (fully covered by the companion
tree-sitter-cooklangspec). - Hosting or publishing that grammar repository (the maintainer's own responsibility, not detailed in either spec).
- Any
folds.scm/indents.scm-driven behavior for.cookfiles (deferred, matching the companion spec's scope decision). - Any change to
dot setup nvim's own success-check logic. - A
~/.github/README.mdcommand-table row — not applicable, since this isn't adotsubcommand. - Automated highlight-assertion tests for the Neovim config.
Further Notes
- This integration can't actually be completed end-to-end until the companion
tree-sitter-cooklangrepo exists and is reachable by a normal git URL —install_info.url/branchhere are placeholders until then. - Mirrors the existing
gitea-axi/gitea-axi-integrationspec pair already in this.claude/spec/directory: one spec for the generic, reusable tool, one for how this specific repo adopts it.