*cp.nvim.txt* Competitive programming plugin for Neovim Author: Barrett Ruth License: Same terms as Vim itself (see |license|) ============================================================================== INTRODUCTION *cp.nvim* cp.nvim is a competitive programming plugin that automates problem setup, compilation, and testing workflow for online judges. Supported platforms (for now!): AtCoder, Codeforces, CSES ============================================================================== REQUIREMENTS *cp-requirements* - Neovim 0.10.0+ - Unix-like operating system - uv package manager (https://docs.astral.sh/uv/) ============================================================================== 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. 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 < 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}' }, } } } < ============================================================================== CONFIGURATION *cp-config* Here's an example configuration with lazy.nvim: >lua { 'barrettruth/cp.nvim', cmd = 'CP', build = 'uv sync', opts = { 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 = { ... } } } }, }, atcoder = { enabled_languages = { 'cpp', 'python' }, default_language = 'cpp', }, codeforces = { enabled_languages = { 'cpp', 'python' }, default_language = 'cpp', }, }, open_url = true, 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'. Platforms select which languages are enabled and which one is the default; per-platform overrides can tweak 'extension' or 'commands'. For example, to run CodeForces contests with Python by default: >lua { platforms = { codeforces = { default_language = 'python', }, }, } < Any language is supported provided the proper configuration. For example, to run CSES problems with Rust using the single schema: >lua { 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) Per-platform enablement, default language, and optional overrides. {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. {open_url} (boolean) Open the contest & problem url in the browser when the contest is first opened. *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: ~ {before_run} (function, optional) Called before test panel opens. function(state: cp.State) {before_debug} (function, optional) Called before debug build/run. function(state: cp.State) {setup_code} (function, optional) Called after source file is opened. function(state: cp.State) {setup_io_input} (function, optional) Called when I/O input buffer created. function(bufnr: integer, state: cp.State) Default: helpers.clearcol (removes line numbers/columns) {setup_io_output} (function, optional) Called when I/O output buffer created. function(bufnr: integer, state: cp.State) Default: helpers.clearcol (removes line numbers/columns) Hook functions receive the cp.nvim state object (|cp.State|). See |lua/cp/state.lua| for available methods and fields. The I/O buffer hooks are called once when the buffers are first created during problem setup. Use these to customize buffer appearance (e.g., remove line numbers, set custom options). Access helpers via: >lua local helpers = require('cp').helpers < Example usage: >lua hooks = { setup_code = function(state) print("Setting up " .. state.get_base_name()) print("Source file: " .. state.get_source_file()) end, setup_io_input = function(bufnr, state) -- Custom setup for input buffer vim.api.nvim_set_option_value('number', false, { buf = bufnr }) end } < ============================================================================== 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 ============================================================================== 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 solutions on AtCoder website ============================================================================== 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 setup_io_input and 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. ============================================================================== ANSI COLORS AND HIGHLIGHTING *cp-ansi* cp.nvim provides comprehensive ANSI color support and highlighting for compiler output, program stderr, and diff visualization. If you cannot see color highlighting in your config, it is likely due to an erroneous config. Most tools (GCC, Python, Clang, Rustc) color stdout based on whether stdout is connected to a terminal. One can usually get aorund this by leveraging flags to force colored output. For example, to force colors with GCC, alter your config as follows: >lua { commands = { build = { 'g++', '-fdiagnostics-color=always', ... } } } < ============================================================================== HIGHLIGHT GROUPS *cp-highlights* Test Status Groups ~ All test status groups link to builtin highlight groups, automatically adapting to your colorscheme: CpTestAC Links to DiagnosticOk (AC status) CpTestWA Links to DiagnosticError (WA status) CpTestTLE Links to DiagnosticWarn (TLE status) CpTestMLE Links to DiagnosticWarn (MLE status) CpTestRTE Links to DiagnosticHint (RTE status) CpTestNA Links to Comment (pending/unknown status) ANSI Color Groups ~ cp.nvim preserves ANSI colors from compiler output and program stderr using a sophisticated parsing system. Colors are automatically mapped to your terminal colorscheme via vim.g.terminal_color_* variables. Diff Highlighting ~ The git diff backend uses Neovim's built-in highlight groups that automatically adapt to your colorscheme: DiffAdd Highlights added text in git diffs DiffDelete Highlights removed text in git diffs ============================================================================== TERMINAL COLOR INTEGRATION *cp-terminal-colors* ANSI colors automatically use the terminal's color palette through Neovim's vim.g.terminal_color_* variables. ============================================================================== HIGHLIGHT CUSTOMIZATION *cp-highlight-custom* Customize highlight groups after your colorscheme loads: >lua vim.api.nvim_create_autocmd('ColorScheme', { callback = function() vim.api.nvim_set_hl(0, 'CpTestAC', { link = 'String' }) end }) ============================================================================== HELPERS *cp-helpers* The helpers module provides utility functions for buffer customization. Access via: >lua local helpers = require('cp').helpers < Functions ~ helpers.clearcol({bufnr}) *helpers.clearcol* Remove line numbers, columns, and signs from buffer. Sets: • number = false • relativenumber = false • signcolumn = 'no' • statuscolumn = '' Parameters: ~ {bufnr} (integer) Buffer handle ============================================================================== PANEL KEYMAPS *cp-panel-keys* Navigate to next test case Navigate to previous test case t Cycle through configured diff modes (see |cp.PanelConfig|) q Exit panel and restore layout Exit interactive terminal and restore layout Diff Modes ~ Three diff modes are available: side-by-side Expected and actual output shown side-by-side (default) vim Built-in vim diff (always available) git Character-level git word-diff (requires git, more precise) Configure which modes to cycle through via |cp.PanelConfig|.diff_modes. The first element is used as the default mode. The git backend shows character-level changes with [-removed-] and {+added+} markers. Execution Details ~ Test cases are executed individually using the same compilation and execution pipeline, but with isolated input/output for precise failure analysis. ============================================================================== FILE STRUCTURE *cp-files* cp.nvim creates the following file structure upon problem setup: > {problem_id}.{ext} " Source file build/ {problem_id}.run " Compiled binary io/ {problem_id}.n.cpin " nth test input {problem_id}.n.cpout " nth test expected output < ============================================================================== HEALTH CHECK *cp-health* Run |:checkhealth| cp to verify your setup. vim:tw=78:ts=8:ft=help:norl: