- Fuse search() and available_labels() into a single scan() pass.
Drops the line_index bookkeeping field on match records and one
full traversal of the visible buffer.
- Replace the separate LABELS array with direct indexing into
M.config.labels (a string, ~26 ASCII chars). One less parallel
data structure; no fn.split at setup, no bottom-of-file auto-setup
call needed.
- Label picker switched from nested O(M*L) scan to an O(M+L) cursor
walk. No more double-duty 'avail' set acting as both conflict-set
and consumed-label marker.
- Termcode constants consolidated into a K = { ... } table using
vim.keycode.
- Normalize module state: CONFIG -> M.config.
- Collapse 'if opts then extend end' to 'opts or {}'.
- Fix: hoist create_augroup out of the table-valued label branch so
a second setup() call with a string label clears any stale autocmd
from a prior table-valued call.
- Drop redundant '#line > 0' guard in scan (string.find handles
empty lines correctly).
Net: 186 -> 148 lines. Public API unchanged.