Add LuaCATS annotations to the env conversion helper and drop the table.sort call since ordering is not required by uv.spawn.
Co-authored-by: Codex <noreply@openai.com>
Neovim/libuv spawn expects env as a list of KEY=VALUE strings. Passing the map from vim.fn.environ() can fail process startup with ENOENT, which breaks NDJSON test scraping and surfaces as 'Failed to start scraper process'.\n\nConvert env map to a deterministic list before uv.spawn in the NDJSON scraper path.
Co-authored-by: Codex <noreply@openai.com>
Problem: time and timeout were listed as optional dependencies despite
being required for plugin initialization. nix was not mentioned as an
alternative to uv for the Python scraping environment.
Solution: rename section to "Dependencies", list time/timeout first,
and add nix as an alternative to uv for scraping.
Problem: setup_python_env() is called from check_required_runtime()
during config.setup(), which runs on the very first :CP command. The
uv sync and nix build calls use vim.system():wait(), blocking the
Neovim event loop. During the block the UI is frozen and
vim.schedule-based log messages never render, so the user sees an
unresponsive editor with no feedback.
Solution: remove setup_python_env() from check_required_runtime() so
config init is instant. Call it lazily from run_scraper() instead,
only when a scraper subprocess is actually needed. Use vim.notify +
vim.cmd.redraw() before blocking calls so the notification renders
immediately via a forced screen repaint, rather than being queued
behind vim.schedule.
Problem: with debug = true, there is not enough diagnostic output to
troubleshoot environment or execution issues. The resolved python path,
scraper commands, and compile/run shell commands are not logged.
Solution: add logger.log calls at key decision points: python env
resolution (nix vs uv vs discovery), uv sync stderr output, scraper
subprocess commands, and compile/run shell strings. All gated behind
the existing debug flag so they only appear when debug = true.
Problem: setup_python_env() skips uv sync when .venv/ exists. If a
previous sync was interrupted (e.g. network timeout), the directory
exists but is broken, and every subsequent session silently uses a
corrupt environment.
Solution: remove the isdirectory guard and always run uv sync. It is
idempotent and near-instant when dependencies are already installed,
so the only cost is one subprocess call per session.
Problem: tbl_deep_extend merges user platforms on top of defaults, so
all four default platforms survive even when the user only configures a
subset. The picker then shows platforms the user never intended to use.
Solution: before the deep merge, prune any default platform not present
in the user's platforms table. This preserves per-platform default
filling (the user doesn't have to re-specify every field) while ensuring
only explicitly configured platforms appear.
Problem: when required dependencies (GNU time/timeout, Python env) are
missing, config.setup() throws a raw error() that surfaces as a Lua
traceback. On macOS without coreutils the message is also redundant
("GNU time not found: GNU time not found") and offers no install hint.
Solution: wrap config.setup() in pcall inside ensure_initialized(),
strip the Lua source-location prefix, and emit a vim.notify at ERROR
level. Add Darwin-specific install guidance to the GNU time/timeout
not-found messages. Pass capability reasons directly instead of
wrapping them in a redundant outer message.
Problem: the vimdoc had no setup section, and configuration was buried
after commands and mappings.
Solution: add a cp-setup section with lazy.nvim example and move both
setup and configuration above commands for better discoverability.
Problem: users who want keybindings must call vim.cmd('CP run') or
reach into internal Lua modules directly. There is no stable,
discoverable, lazy-load-friendly public API for key binding.
Solution: define 7 <Plug> mappings in plugin/cp.lua that dispatch
through the same handle_command() code path as :CP. Document them
in a new MAPPINGS section in the vimdoc with helptags and an example
config block.
Problem: the deprecated vim.g.cp_config fallback was kept for
backwards compatibility after the rename to vim.g.cp in v0.7.6.
Solution: drop the shim entirely and update the setup() deprecation
target to v0.7.7.
Problem: when opening a contest for the first time (metadata not
cached), the setup_code hook fired before state.set_language() was
called, causing state.get_language() to return nil inside the hook.
Solution: call state.set_language(lang) before the hook in the
provisional-buffer branch of setup_contest(). The value is already
computed at that point and is identical to what setup_problem() sets
later, so the early write is idempotent.