6e80d5db

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.
coverage-reporte2e-testexample-switzerland-taxesexample-switzerland-vatpackagepre-commitshellvim-pluginvim-syntaxweeder-checkconfiguredevShelldefaultmutation-centjesmutation-centjes-diffx86_64-linux