By: Tom Sydney Kerckhove <syd@cs-syd.eu>
Highlight every syntax element in the vim plugin The syntax file was ten unanchored regexes, and it drifted twice. `lot` and `+ assert virtual` were added to it, but the virtual account assertions were not, and `@`, `=`, `/`, `~` and `%` had never been highlighted at all, nor had the account types, tag names, an account name with no colon in it, or an attachment path with no slash in it. Unanchored patterns also fire inside words. `account lottery` highlighted `lot`, `account vintage` highlighted `tag`, and a timestamp with seconds had `14:56:53` claimed by the account-name rule, which matches a time as readily as a name. Each declaration is a chain now: a line-anchored item names it, `nextgroup` says what may follow, and everything downstream is `contained`. That is the lexer's start codes in vim's terms, and it is what makes `lot` highlight in a posting and stay plain text in a description -- the word is only reachable after a currency symbol. The chains are deliberately looser than the grammar about continuation: one currency-symbol item serves every position a currency symbol can appear in, with the union of their nextgroups. Over-permissive continuation can only mis-highlight input that does not parse, whereas one item per position would multiply near-identical items. Definition order is load-bearing, because vim gives a position to the item defined last. `currency` and the virtual scopes sit exactly where an assertion's account name would, so they only win by being defined after it. The lexer resolves the same ambiguity by preferring its longest match, so the two agree by construction rather than by coincidence. Groups are named and linked rather than written as bare `Keyword` matches, so each one is overridable. `@`, `~` and `=` link to `Keyword` alongside `lot`, because each decides what the amount beside it means, and `lot @` is one marker; `/` and `%` link to `Constant`, because `1 / 7` and `10%` are each one rational value, the way the grammar has them. `Operator` goes unused: it is the apt group, but a colourscheme that leaves it unstyled renders exactly the tokens whose absence is an accounting error as plain text. checks.vim-syntax pins all of it. The corpus covers every token the lexer produces plus the words that used to false-positive, and `centjes format` accepts it and is idempotent on it, so it is the real syntax rather than an invention. The golden dump records the group of every run of characters and what each group links to -- without the second part the check would pass with every operator uncoloured, which is how they went missing in the first place. Both vim and neovim are checked, and they agree.