*cp.nvim.txt* Competitive programming plugin for Neovim Author: Barrett Ruth License: Same terms as Vim itself (see |license|) ============================================================================== CONTENTS *cp-contents* 1. Introduction .................................................. |cp.nvim| 2. Requirements ........................................ |cp-requirements| 3. Setup ........................................................ |cp-setup| 4. Configuration ................................................ |cp-config| 5. Commands .................................................. |cp-commands| 6. Mappings .................................................. |cp-mappings| 7. Language Selection .................................. |cp-lang-selection| 8. Workflow .................................................. |cp-workflow| 9. Workflow Example ............................................ |cp-example| 10. Verdict Formatting ................................. |cp-verdict-format| 11. Picker Integration .......................................... |cp-picker| 12. Picker Keymaps ........................................ |cp-picker-keys| 13. Panel ........................................................ |cp-panel| 14. Interactive Mode .......................................... |cp-interact| 15. Stress Testing .............................................. |cp-stress| 16. Race .......................................................... |cp-race| 17. Credentials ............................................ |cp-credentials| 18. Submit ...................................................... |cp-submit| 19. Submit Language Versions ......................... |cp-submit-language| 20. Open ......................................................... |cp-open| 21. ANSI Colors ................................................... |cp-ansi| 22. Highlight Groups ........................................ |cp-highlights| 23. Terminal Colors .................................... |cp-terminal-colors| 24. Highlight Customization .......................... |cp-highlight-custom| 25. Helpers .................................................... |cp-helpers| 26. Statusline Integration .................................. |cp-statusline| 27. Panel Keymaps .......................................... |cp-panel-keys| 28. File Structure ................................................ |cp-files| 28. Health Check ................................................ |cp-health| ============================================================================== INTRODUCTION *cp.nvim* cp.nvim is a competitive programming plugin that automates problem setup, compilation, and testing workflow for online judges. Supported platforms: AtCoder, CodeChef, Codeforces, CSES, Kattis, USACO ============================================================================== REQUIREMENTS *cp-requirements* - Neovim 0.10.0+ - Unix-like operating system - uv package manager (https://docs.astral.sh/uv/) ============================================================================== SETUP *cp-setup* Load cp.nvim with your package manager. For example, with lazy.nvim: >lua { 'barrettruth/cp.nvim' } < The plugin works automatically with no configuration required. For customization, see |cp-config|. ============================================================================== CONFIGURATION *cp-config* Configuration is done via `vim.g.cp`. Set this before using the plugin: >lua vim.g.cp = { languages = { cpp = { extension = 'cc', commands = { build = { 'g++', '-std=c++17', '{source}', '-o', '{binary}', '-fdiagnostics-color=always' }, run = { '{binary}' }, debug = { 'g++', '-std=c++17', '-fsanitize=address,undefined', '{source}', '-o', '{binary}' }, }, }, python = { extension = 'py', commands = { run = { 'python', '{source}' }, debug = { 'python', '{source}' }, }, }, }, platforms = { cses = { enabled_languages = { 'cpp', 'python' }, default_language = 'cpp', overrides = { cpp = { extension = 'cpp', commands = { build = { ... } } } }, }, }, debug = false, ui = { ansi = true, run = { width = 0.3, next_test_key = '', -- or nil to disable prev_test_key = '', -- or nil to disable }, panel = { diff_modes = { 'side-by-side', 'git', 'vim' }, max_output_lines = 50, }, diff = { git = { args = { 'diff', '--no-index', '--word-diff=plain', '--word-diff-regex=.', '--no-prefix' }, }, }, picker = 'telescope', }, } < By default, C++ (g++ with ISO C++17) and Python are preconfigured under 'languages'. All six platforms are enabled by default. User-supplied platform entries are merged on top of the defaults — you only need to specify what you want to change. To disable a platform entirely, set it to `false`. For example, to run Codeforces contests with Python by default and disable CodeChef: >lua vim.g.cp = { platforms = { codeforces = { default_language = 'python', }, codechef = false, }, } < Any language is supported provided the proper configuration. For example, to add Rust and use it by default on CSES: >lua vim.g.cp = { languages = { rust = { extension = 'rs', commands = { build = { 'rustc', '{source}', '-o', '{binary}' }, run = { '{binary}' }, }, }, }, platforms = { cses = { enabled_languages = { 'cpp', 'python', 'rust' }, default_language = 'rust', }, }, } < *cp.Config* Fields: ~ {languages} (table) Global language registry. Each language provides an {extension} and {commands}. {platforms} (table) All six platforms are enabled by default. Each entry is merged on top of the platform defaults — omitted fields keep their defaults and unmentioned platforms stay enabled. Set a platform key to `false` to disable it entirely. {hooks} (|cp.Hooks|) Hook functions called at various stages. {debug} (boolean, default: false) Show info messages. {scrapers} (string[]) Supported platform ids. {filename} (function, optional) function(contest, contest_id, problem_id, config, language): string Should return full filename with extension. (default: concatenates contest_id and problem_id, lowercased) {ui} (|CpUI|) UI settings: panel, diff backend, picker. *CpPlatform* Fields: ~ {enabled_languages} (string[]) Language ids enabled on this platform. {default_language} (string) One of {enabled_languages}. {overrides} (table, optional) Per-language overrides of {extension} and/or {commands}. *CpLanguage* Fields: ~ {extension} (string) File extension without leading dot. {commands} (|CpLangCommands|) Command templates. *CpLangCommands* Fields: ~ {build} (string[], optional) For compiled languages. Must include {source} and {binary}. {run} (string[], optional) Runtime command. Compiled: must include {binary}. Interpreted: must include {source}. {debug} (string[], optional) Debug variant; same token rules as {build} (compiled) or {run} (interpreted). *CpUI* Fields: ~ {ansi} (boolean, default: true) Enable ANSI color parsing and highlighting in both I/O view and panel. {run} (|RunConfig|) I/O view configuration. {panel} (|PanelConfig|) Test panel behavior configuration. {diff} (|DiffConfig|) Diff backend configuration. {picker} (string|nil) 'telescope', 'fzf-lua', or nil. *RunConfig* Fields: ~ {width} (number, default: 0.3) Width of I/O view splits as fraction of screen (0.0 to 1.0). {next_test_key} (string|nil, default: '') Keymap to navigate to next test in I/O view. Set to nil to disable. {prev_test_key} (string|nil, default: '') Keymap to navigate to previous test in I/O view. Set to nil to disable. {format_verdict} (|VerdictFormatter|, default: nil) Custom verdict line formatter. See |cp-verdict-format|. *EditConfig* Fields: ~ {next_test_key} (string|nil, default: ']t') Jump to next test. {prev_test_key} (string|nil, default: '[t') Jump to previous test. {delete_test_key} (string|nil, default: 'gd') Delete current test. {add_test_key} (string|nil, default: 'ga') Add new test. {save_and_exit_key} (string|nil, default: 'q') Save and exit editor. All keys are nil-able. Set to nil to disable. *cp.PanelConfig* Fields: ~ {diff_modes} (string[], default: {'side-by-side', 'git', 'vim'}) List of diff modes to cycle through with 't' key. First element is the default mode. Valid modes: 'side-by-side', 'git', 'vim'. {max_output_lines} (number, default: 50) Maximum lines of test output. *cp.DiffConfig* Fields: ~ {git} (|cp.DiffGitConfig|) Git diff backend configuration. *cp.DiffGitConfig* Fields: ~ {args} (string[]) Command-line arguments for git diff. Default: { 'diff', '--no-index', '--word-diff=plain', '--word-diff-regex=.', '--no-prefix' } • --no-index: Compare files outside git repository • --word-diff=plain: Character-level diff markers • --word-diff-regex=.: Split on every character • --no-prefix: Remove a/ b/ prefixes from output *cp.Hooks* Fields: ~ {setup} (|cp.CpSetupHooks|, optional) One-time initialization hooks. {on} (|cp.CpOnHooks|, optional) Recurring event hooks. *cp.CpSetupHooks* Fields: ~ {contest} (function, optional) Called once when a contest directory is first created (not on subsequent visits). function(state: cp.State) {code} (function, optional) Called after the source buffer is opened for the first time (guarded by cp_setup_done). function(state: cp.State) {io} (|cp.CpSetupIOHooks|, optional) I/O buffer hooks. *cp.CpSetupIOHooks* Fields: ~ {input} (function, optional) Called when the I/O input buffer is created. function(bufnr: integer, state: cp.State) Default: helpers.clearcol {output} (function, optional) Called when the I/O output buffer is created. function(bufnr: integer, state: cp.State) Default: helpers.clearcol *cp.CpOnHooks* Fields: ~ {enter} (function, optional) Called on every BufEnter on the solution buffer. Registered as a buffer-scoped autocmd and fired immediately after setup.code. function(state: cp.State) {run} (function, optional) Called before the test panel opens. function(state: cp.State) {debug} (function, optional) Called before a debug run. function(state: cp.State) All hook functions receive the cp.nvim state object (|cp.State|). See |lua/cp/state.lua| for available methods and fields. Example usage: >lua hooks = { setup = { contest = function(state) local dir = vim.fn.fnamemodify( state.get_source_file(state.get_language()), ':h') vim.fn.system({ 'cp', '~/.clang-format', dir .. '/.clang-format' }) end, code = function(state) vim.opt_local.foldmethod = 'marker' vim.diagnostic.enable(false) end, }, on = { enter = function(state) vim.opt_local.winbar = '' end, run = function(state) require('config.lsp').format() end, }, } < ============================================================================== COMMANDS *cp-commands* :CP *:CP* cp.nvim uses a single :CP command with intelligent argument parsing: Setup Commands ~ :CP {platform} {contest_id} [--lang {language}] Full setup: set platform and load contest metadata. Scrapes test cases and creates source file. --lang: Use specific language (default: platform default) Examples: > :CP codeforces 1933 :CP codeforces 1933 --lang python < View Commands ~ :CP run [all|n|n,m,...] [--debug] Run tests in I/O view (see |cp-io-view|). Lightweight split showing test verdicts. Execution modes: • :CP run Combined: single execution with all tests (auto-switches to individual when multiple samples) • :CP run all Individual: N separate executions • :CP run n Individual: run test n only • :CP run n,m,... Individual: run specific tests (e.g. nth and mth) --debug: Use debug build (builds to build/.dbg) Combined mode runs all test inputs in one execution (matching platform behavior for multi-test problems). When a problem has multiple independent sample test cases, :CP run auto-switches to individual mode to run each sample separately. Examples: > :CP run " Combined: all tests, one execution :CP run all " Individual: all tests, N executions :CP run 2 " Individual: test 2 only :CP run 1,3,5 " Individual: tests 1, 3, and 5 :CP run all --debug " Individual with debug build < :CP panel [--debug] [n] Open full-screen test panel (see |cp-panel|). Aggregate table with diff modes for detailed analysis. Optional [n] focuses on specific test. --debug: Use debug build (with sanitizers, etc.) Examples: > :CP panel " All tests :CP panel --debug 3 " Test 3, debug build < :CP pick [--lang {language}] Launch configured picker for interactive platform/contest selection. --lang: Pre-select language for chosen contest. Example: > :CP pick :CP pick --lang python < :CP interact [script] Open an interactive terminal for the current problem. If an executable interactor is provided, runs the compiled binary against the source file (see *cp-interact*). Otherwise, runs the source file. Only valid for interactive problems. :CP stress [generator] [brute] Start an automated stress test loop against a brute-force reference. Toggles off if already running. Without arguments, auto-detects a generator and brute script in the working directory. See |cp-stress|. Navigation Commands ~ :CP next [--lang {language}] Navigate to next problem in current contest. Stops at last problem (no wrapping). --lang: Use specific language for next problem. By default, preserves current file's language if enabled for the new problem, otherwise uses platform default. Examples: > :CP next :CP next --lang python < :CP prev [--lang {language}] Navigate to previous problem in current contest. Stops at first problem (no wrapping). --lang: Use specific language for previous problem. By default, preserves current file's language if enabled for the new problem, otherwise uses platform default. Examples: > :CP prev :CP prev --lang cpp < :CP {problem_id} [--lang {language}] Jump to problem {problem_id} in a contest. Requires that a contest has already been set up. --lang: Use specific language for this problem. Examples: > :CP B :CP C --lang python < Edit Commands ~ :CP edit [n] Open grid test editor showing all test cases. Tests displayed as 2×N grid (2 rows, N columns): • Top row: Test inputs (editable) • Bottom row: Expected outputs (editable) Optional [n]: Jump cursor to test n's input buffer Changes saved to both cache and disk on exit, taking effect immediately in :CP run and CLI. Keybindings (configurable via |EditConfig|): q Save all and exit editor ]t Jump to next test column [t Jump to previous test column gd Delete current test column ga Add new test column at end Normal window navigation Examples: > :CP edit " Edit all tests :CP edit 3 " Edit all, start at test 3 < Race Commands ~ :CP {platform} {contest_id} --race [--lang {language}] Start a countdown to the contest's scheduled start time. At T=0, automatically runs: :CP {platform} {contest_id} [--lang ...] Examples: > :CP atcoder abc400 --race :CP codeforces 2100 --race --lang python < Credential Commands ~ :CP login [platform] Set or update stored credentials for a platform. Prompts for username and password, overwriting any previously saved credentials. If [platform] is omitted, uses the active platform. Examples: > :CP login atcoder :CP login codeforces < :CP logout [platform] Remove stored credentials for a platform. If [platform] is omitted, uses the active platform. Examples: > :CP logout atcoder < :CP {platform} signup Open the platform's registration page in the browser via |vim.ui.open|. Works even if {platform} is not enabled in your config. Examples: > :CP atcoder signup :CP codeforces signup < Submit Commands ~ :CP submit [--lang {language}] Submit the current solution to the online judge. Uses stored credentials (set via :CP login). Prompts on first use if no credentials are saved. --lang: Submit solution for a specific language. :CP open [problem|contest|standings] Open the URL for the current problem, contest, or standings page in the browser via |vim.ui.open|. Defaults to "problem" if no argument is given. Warns if the URL is not available (e.g. CSES has no standings). Examples: > :CP open :CP open contest :CP open standings < State Restoration ~ :CP Restore state from current file. Automatically detects platform, contest, problem, and language from cached state. Use this after switching files to restore your CP environment. Cache Commands ~ :CP cache clear [platform] [contest] Clear cache data at different granularities: • No args: Clear all cached data • [platform]: Clear all data for a platform • [platform] [contest]: Clear specific contest Examples: > :CP cache clear :CP cache clear codeforces :CP cache clear codeforces 1848 < :CP cache read View the cache in a pretty-printed lua buffer. Exit with q. Template Variables ~ *cp-template-vars* Command templates support variable substitution using {variable} syntax: • {source} Source file path (e.g. "abc324a.cpp") • {binary} Output binary path (e.g. "build/abc324a.run" or "build/abc324a.dbg" for debug builds) Example template: > build = { 'g++', '{source}', '-o', '{binary}', '-std=c++17' } < Would expand to: > g++ abc324a.cpp -o build/abc324a.run -std=c++17 < Debug Builds ~ *cp-debug-builds* The --debug flag uses the debug command configuration instead of build: • Normal build: commands.build → outputs to build/.run • Debug build: commands.debug → outputs to build/.dbg Debug builds typically include sanitizers (address, undefined behavior) to catch memory errors, buffer overflows, and other issues. Both binaries coexist, so you can switch between normal and debug mode without recompiling. Example debug configuration: > languages = { cpp = { extension = 'cc', commands = { build = { 'g++', '-std=c++17', '{source}', '-o', '{binary}' }, run = { '{binary}' }, debug = { 'g++', '-std=c++17', '-fsanitize=address,undefined', '{source}', '-o', '{binary}' }, } } } < ============================================================================== MAPPINGS *cp-mappings* cp.nvim provides mappings for all primary actions. These dispatch through the same code path as |:CP|. *(cp-run)* (cp-run) Run tests in I/O view. Equivalent to :CP run. *(cp-panel)* (cp-panel) Open full-screen test panel. Equivalent to :CP panel. *(cp-edit)* (cp-edit) Open the test case editor. Equivalent to :CP edit. *(cp-next)* (cp-next) Navigate to the next problem. Equivalent to :CP next. *(cp-prev)* (cp-prev) Navigate to the previous problem. Equivalent to :CP prev. *(cp-pick)* (cp-pick) Launch the contest picker. Equivalent to :CP pick. *(cp-interact)* (cp-interact) Open interactive mode. Equivalent to :CP interact. *(cp-stress)* (cp-stress) Run stress test loop. Equivalent to :CP stress. *(cp-submit)* (cp-submit) Submit current solution. Equivalent to :CP submit. *(cp-open)* (cp-open) Open current problem URL in browser. Equivalent to :CP open. Example configuration: >lua vim.keymap.set('n', 'cr', '(cp-run)') vim.keymap.set('n', 'cp', '(cp-panel)') vim.keymap.set('n', 'ce', '(cp-edit)') vim.keymap.set('n', 'cn', '(cp-next)') vim.keymap.set('n', 'cN', '(cp-prev)') vim.keymap.set('n', 'cc', '(cp-pick)') vim.keymap.set('n', 'ci', '(cp-interact)') vim.keymap.set('n', 'cs', '(cp-stress)') vim.keymap.set('n', 'cu', '(cp-submit)') < ============================================================================== LANGUAGE SELECTION *cp-lang-selection* cp.nvim supports multiple languages per problem. Each platform enables specific languages and has a default. You can override the language for any setup or navigation command using the --lang flag. Language Selection Behavior ~ When setting up or navigating to a problem: 1. Explicit --lang flag takes highest priority 2. If no --lang flag, tries to preserve current file's language (only if that language is enabled for the new problem) 3. Falls back to platform's default language Multiple Solution Files ~ Different languages create different solution files. For example: 1848a.cc (C++ solution) 1848a.py (Python solution) Both files can exist simultaneously with their own state. Switching between languages means switching between different files. Examples ~ > :CP codeforces 1848 " Use platform default (likely C++) :CP codeforces 1848 --lang python " Use Python explicitly " In 1848a.cc (C++ file): :CP next " Next problem tries to use C++ :CP next --lang python " Next problem uses Python " In 1848a.py (Python file): :CP next " Next problem tries to use Python :CP next --lang cpp " Next problem switches to C++ < Language Validation ~ If you request a language that isn't enabled for a platform, cp.nvim will show a helpful error message listing available languages for that platform. ============================================================================== WORKFLOW *cp-workflow* For the sake of consistency and simplicity, cp.nvim extracts contest/problem identifiers from URLs. This means that, for example, CodeForces/AtCoder contests are configured by their round id rather than round number. See below. ============================================================================== PLATFORM-SPECIFIC USAGE *cp-platforms* AtCoder ~ *cp-atcoder* URL format: https://atcoder.jp/contests/{contest_id}/tasks/{contest_id}_{problem_id} Usage examples: > :CP atcoder abc324 " Set up atcoder.jp/contests/abc324 :CP atcoder abc324 --lang python " Set up with Python instead of default Codeforces ~ *cp-codeforces* URL format: https://codeforces.com/contest/{contest_id}/problem/{problem_id} Usage examples: > :CP codeforces 1934 " Set up codeforces.com/contest/1934 :CP codeforces 1934 --lang cpp " Set up with C++ CSES ~ *cp-cses* URL format: https://cses.fi/problemset/task/{problem_id} Usage examples: > :CP cses dynamic_programming " Set up all problems in dp category CodeChef ~ *cp-codechef* URL format: https://www.codechef.com/{contest_id}/problems/{problem_id} The contest_id is the contest code from the URL (e.g. START209). Usage examples: > :CP codechef START209 " Set up codechef.com/START209 USACO ~ *cp-usaco* URL format: https://usaco.org/index.php?page=viewproblem2&cpid={cpid} The contest_id combines the abbreviated month, two-digit year, and division in lowercase, joined by underscores (e.g. dec24_gold, feb23_silver). Usage examples: > :CP usaco dec24_gold " Set up December 2024 Gold division :CP usaco feb23_silver " Set up February 2023 Silver division Kattis ~ *cp-kattis* Kattis supports single-problem and full-contest modes. Single problem — the contest_id is the problem slug from the URL: URL format: https://open.kattis.com/problems/{slug} Full contest — the contest_id is the contest ID from the URL. All problems are set up at once with :CP next/:CP prev navigation: URL format: https://open.kattis.com/contests/{id} Usage examples: > :CP kattis primesieve " Single problem :CP kattis t8tnpe " Full contest (all problems, A–H navigation) ============================================================================== COMPLETE WORKFLOW EXAMPLE *cp-example* Example: Setting up and solving AtCoder contest ABC324 1. Browse to https://atcoder.jp/contests/abc324 2. Set up entire contest (bulk setup): > :CP atcoder abc324 < This scrapes all test case data, downloads all test cases, and opens the first problem. 3. Code your solution, then test: > :CP run < View test verdicts in I/O splits. For detailed analysis: > :CP panel < Navigate tests with /, exit with q 4. Move to next problem: > :CP next < This automatically sets up the next problem (likely problem B) 5. Continue solving problems with :CP next/:CP prev navigation 6. Try a different language for a problem: > :CP C --lang python < Opens problem C with Python instead of C++ 7. Switch to another file (e.g. previous contest): > :e ~/contests/abc323/a.cpp :CP < Automatically restores abc323 contest context 8. Submit solution: > :CP submit < Uses stored credentials and submits to AtCoder. ============================================================================== I/O VIEW *cp-io-view* The I/O view provides lightweight test feedback in persistent side splits. Test outputs are concatenated with verdict summaries at the bottom. The |cp-panel| offers more fine-grained analysis with diff modes. Execution Modes ~ The I/O view supports two execution modes: Combined Mode (:CP run with single sample) • Single execution with all test inputs concatenated • Matches platform behavior (e.g. Codeforces multi-test format) • Shows one verdict for the entire execution • Input split: All test inputs concatenated • Output split: Single program output + verdict • Used when problem has one sample containing multiple test cases Individual Mode (:CP run all / :CP run n / :CP run n,m,...) • Separate execution for each test case • Per-test verdicts for debugging • Input split: Selected test inputs concatenated • Output split: All test outputs concatenated + per-test verdicts • Auto-selected when problem has multiple independent samples Layout ~ The I/O view appears as 30% width splits on the right side: > ┌──────────────────────────┬─────────────────────────────────────────────┐ │ │ Output (Top Split) │ │ │ 5 510 │ │ │ │ │ │ 7 714 │ │ Solution Code │ │ │ │ Test 1: WA | 212.07/2000 ms | 1/512 MB |...│ │ │ Test 2: WA | 81.94/2000 ms | 1/512 MB |...│ │ ├─────────────────────────────────────────────┤ │ │ Input (Bottom Split) │ │ │ 1 2 3 │ │ │ │ │ │ 4 5 6 │ └──────────────────────────┴─────────────────────────────────────────────┘ < The output split shows: 1. Program output (raw, preserving all formatting) 2. Space-aligned verdict summary with: - Test number and status (AC/WA/TLE/MLE/RTE with color highlighting) - Runtime: actual/limit in milliseconds - Memory: actual/limit in megabytes - Exit code (with signal name for crashes) Usage ~ :CP run Combined mode: all tests in one execution :CP run all Individual mode: all tests separately :CP run 3 Individual mode: test 3 only :CP run 1,3,5 Individual mode: specific tests (1, 3, and 5) Navigation ~ While in the I/O view buffers, use the configured keymaps to cycle through tests: Next test (default, see |RunConfig|.next_test_key) Previous test (default, see |RunConfig|.prev_test_key) Buffer Customization ~ Use the hooks.setup.io.input and hooks.setup.io.output hooks (see |cp.Hooks|) to customize buffer appearance. By default, line numbers and columns are removed via helpers.clearcol (see |cp-helpers|). ============================================================================== VERDICT FORMATTING *cp-verdict-format* Customize how verdict summaries appear in the I/O view using format_verdict. Configuration ~ Set ui.run.format_verdict to a function that formats verdict data: >lua format_verdict = function(data) return { line = "...", highlights = {...} } end < Format Function ~ *VerdictFormatter* Input: |VerdictFormatData| table with test results Output: |VerdictFormatResult| table with formatted line and optional highlights *VerdictFormatData* {index} (integer) Test case number {status} (table) { text: string, highlight_group: string } {time_ms} (number) Execution time in milliseconds {time_limit_ms} (number) Time limit in milliseconds {memory_mb} (number) Peak memory usage in megabytes {memory_limit_mb} (number) Memory limit in megabytes {exit_code} (integer) Process exit code {signal} (string|nil) Signal name for crashes (e.g. "SIGSEGV") {time_actual_width} (integer|nil) Dynamic width for time value alignment {time_limit_width} (integer|nil) Dynamic width for time limit alignment {mem_actual_width} (integer|nil) Dynamic width for memory value alignment {mem_limit_width} (integer|nil) Dynamic width for memory limit alignment *VerdictFormatResult* {line} (string) The formatted verdict line {highlights} (table[], optional) Highlight regions: {col_start} (integer) Start column (0-indexed) {col_end} (integer) End column (exclusive) {group} (string) Highlight group name Examples ~ Minimal format: >lua format_verdict = function(data) return { line = string.format("#%d %s", data.index, data.status.text) } end < See |cp-helpers| for alignment functions: pad_right, pad_left, center. ============================================================================== PICKER INTEGRATION *cp-picker* When picker integration is enabled in configuration, cp.nvim provides interactive platform and contest selection using telescope.nvim or fzf-lua. :CP pick *:CP-pick* Launch configured picker for interactive problem selection. Control Flow: Select Platform → Contest → Code! Requires picker = 'telescope' or picker = 'fzf-lua' in configuration. Requires corresponding plugin (telescope.nvim or fzf-lua) to be installed. PICKER KEYMAPS *cp-picker-keys* Force refresh/update contest list. Useful when contest lists are outdated or incomplete ============================================================================== PANEL *cp-panel* The panel provides full-screen test analysis with diff modes for detailed debugging. Problem time/memory limit constraints are in columns Time/Mem respectively. Used time/memory are in columns Runtime/RSS respectively. Access with :CP panel or :CP panel --debug (uses debug build configuration). Interface ~ The panel uses the following table layout: > ┌─────┬────────┬──────────────┬───────────┬──────────┬──────────┬─────────────┐ │ # │ Status │ Runtime (ms) │ Time (ms) │ RSS (MB) │ Mem (MB) │ Exit Code │ ├─────┼────────┼──────────────┼───────────┼──────────┼──────────┼─────────────┤ │ 1 │ AC │ 12.0 │ 2000 │ 123 │ 256 │ 0 │ │ >2 │ WA │ 45.70 │ 2000 │ 100 │ 256 │ 1 │ ├─────┴────────┴──────────────┴───────────┴──────────┴──────────┴─────────────┤ │ Input: │ │ 5 3 │ ├─────┬────────┬──────────────┬───────────┬──────────┬──────────┬─────────────┤ │ 3 │ TLE │ 9.0 │ 2000 │ 256 │ 256 │ 136 (SIGBUS)│ │ 4 │ RTE │ 0.0 │ 2000 │ 256 │ 256 │139 (SIGUSR2)│ └─────┴────────┴──────────────┴───────────┴──────────┴──────────┴─────────────┘ ┌─────────────────────────────────────────────────────────────────────────────┐ │ Expected vs Actual │ │ 423 │ │ 100 │ │ hello world │ └─────────────────────────────────────────────────────────────────────────────┘ Status Indicators ~ Test cases use competitive programming terminology with color highlighting: AC Accepted (passed) WA Wrong Answer (output mismatch) TLE Time Limit Exceeded (timeout) MLE Memory Limit Exceeded Error (heuristic) RTE Runtime Error (other non-zero exit code) NA Any other state < ============================================================================== INTERACTIVE MODE *cp-interact* Run interactive problems manually or with an orchestrator. :CP interact is available for interactive problems. Test cases are ignored in interactive mode (no run panel, no diffs). When using :CP interact {interactor}, the interactor must be executable (chmod +x). Completion after :CP interact suggests executables in CWD. 1) Terminal-only ~ :CP interact Execute the current program and open an interactive terminal running it directly. Use this for manual testing. 2) Orchestrated ~ :CP interact {interactor} Execute the current program and open an interactive terminal that runs your interactor script against it. {interactor} is an executable file relative to the CWD. Example: :CP interact my-executable-interactor.py Keymaps ~ Close the terminal and restore the previous layout. ============================================================================== STRESS TESTING *cp-stress* Start an automated stress test loop to find inputs where your solution disagrees with a brute-force reference. :CP stress [generator] [brute] Start the stress loop. Toggles off if the loop is already running. {generator} Generator script path (default: auto-detected). {brute} Brute-force solution path (default: auto-detected). Auto-detection looks for files named gen.* and brute.* in the CWD. The stress panel opens and streams results for each iteration. On a mismatch, the failing input is displayed in the panel. Keymaps ~ Close the stress panel and restore the previous layout. ============================================================================== RACE *cp-race* Count down to a contest's start time and automatically run setup at T=0. :CP {platform} {contest_id} --race [--lang {language}] Start a countdown timer. At T=0, automatically runs: :CP {platform} {contest_id} [--lang {language}] Examples: > :CP atcoder abc400 --race :CP codeforces 2100 --race --lang python < Starting a new race while one is active automatically cancels the previous one. Statusline integration: see |cp-race-status|. ============================================================================== CREDENTIALS *cp-credentials* Manage stored login credentials for platform submission. Credentials are stored under _credentials in the main cache file (stdpath('data')/cp-nvim.json). Use :CP cache read to inspect them. :CP login [platform] Set or update credentials for a platform. Prompts for username and password, overwriting any previously saved values. Omit [platform] to use the currently active platform. :CP logout [platform] Remove stored credentials for a platform. Omit [platform] to use the currently active platform. :CP {platform} signup Open the platform's account registration page in the browser via |vim.ui.open|. Works even if {platform} is not enabled in your config. {platform} is one of: atcoder, codechef, codeforces, cses, kattis, usaco. ============================================================================== SUBMIT *cp-submit* Submit the current solution to the online judge. :CP submit [--lang {language}] Submit the current solution. Uses stored credentials (set via :CP login). Prompts on first use if no credentials are saved. --lang: Override the language to submit. Platform support: AtCoder Fully implemented. Codeforces Fully implemented. CSES Fully implemented. Kattis Fully implemented. USACO Fully implemented. CodeChef Not yet implemented. See |cp-submit-language| for configuring the language version (e.g. C++20 instead of C++17). ============================================================================== SUBMIT LANGUAGE VERSIONS *cp-submit-language* When submitting, cp.nvim selects a language version for the platform. The default is C++20 for cpp and Python 3 for python. Configuring a version ~ Set {version} globally or per-platform: >lua languages = { cpp = { version = "c++23", ... }, }, platforms = { codeforces = { overrides = { cpp = { version = "c++17" } }, }, }, < Available versions per platform ~ Platform cpp python java rust AtCoder c++20/23 python3, pypy3 java rust Codeforces c++17/20/23 python3, pypy3 - - CSES c++11/17/20 python3, pypy3 java rust2018/2021 Kattis c++17/20/23 python3 java rust USACO c++11/17 python3 java - CodeChef c++20 python3, pypy3 java rust Using a raw platform ID ~ If your preferred version is not listed, you can bypass version lookup by setting {submit_id} to the raw platform language ID: >lua platforms = { codeforces = { overrides = { cpp = { submit_id = "91" } }, }, }, < To find the raw ID, open the platform's submit page in your browser, inspect the language dropdown, and copy the