cp.nvim/doc/cp.txt

367 lines
14 KiB
Text

*cp.txt* Competitive programming plugin for Neovim
Author: Barrett Ruth <br.barrettruth@gmail.com>
License: Same terms as Vim itself (see |license|)
INTRODUCTION *cp* *cp.nvim*
cp.nvim is a competitive programming plugin that automates problem setup,
compilation, and testing workflow for online judges.
Supported platforms: AtCoder, Codeforces, CSES
Supported languages: C++, Python
REQUIREMENTS *cp-requirements*
- Neovim 0.10.0+
- uv package manager (https://docs.astral.sh/uv/)
- Language runtime/compiler (g++, python3)
Optional:
- LuaSnip for template expansion (https://github.com/L3MON4D3/LuaSnip)
COMMANDS *cp-commands*
*:CP*
cp.nvim uses a single :CP command with intelligent argument parsing:
Setup Commands ~
:CP {platform} {contest_id} {problem_id} [--lang={language}]
Full setup: set platform, load contest metadata,
and set up specific problem. Scrapes test cases
and creates source file.
Example: :CP codeforces 1933 a
Example: :CP codeforces 1933 a --lang=python
:CP {platform} {contest_id} Contest setup: set platform and load contest
metadata for navigation. Caches problem list.
Example: :CP atcoder abc324
:CP {platform} Platform setup: set platform only.
Example: :CP cses
:CP {problem_id} [--lang={language}]
Problem switch: switch to different problem
within current contest context.
Example: :CP b (switch to problem b)
Example: :CP b --lang=python
Action Commands ~
:CP run Compile and run current problem with test input.
Shows execution time and output comparison.
:CP debug Compile with debug flags and run current problem.
Includes sanitizers and debug symbols.
:CP test Toggle test panel for individual test case
debugging. Shows per-test results with
vim-native navigation and execution controls.
Navigation Commands ~
:CP next Navigate to next problem in current contest.
Stops at last problem (no wrapping).
:CP prev Navigate to previous problem in current contest.
Stops at first problem (no wrapping).
CONFIGURATION *cp-config*
cp.nvim works out of the box. No setup required.
Optional configuration with lazy.nvim: >
{
'barrett-ruth/cp.nvim',
cmd = 'CP',
opts = {
debug = false,
contests = {
codeforces = {
cpp = {
compile = {
'g++', '-std=c++{version}', '-O2', '-Wall', '-Wextra',
'-DLOCAL', '{source}', '-o', '{binary}',
},
run = { '{binary}' },
debug = {
'g++', '-std=c++{version}', '-g3',
'-fsanitize=address,undefined', '-DLOCAL',
'{source}', '-o', '{binary}',
},
version = 23,
extension = "cc",
},
python = {
run = { 'python3', '{source}' },
debug = { 'python3', '{source}' },
extension = "py",
},
default_language = "cpp",
timeout_ms = 2000,
},
},
hooks = {
before_run = function(ctx) vim.cmd.w() end,
before_debug = function(ctx)
-- ctx.problem_id, ctx.platform, ctx.source_file, etc.
vim.cmd.w()
end,
setup_code = function(ctx)
vim.wo.foldmethod = "marker"
vim.wo.foldmarker = "{{{,}}}"
vim.diagnostic.enable(false)
end,
},
snippets = { ... }, -- LuaSnip snippets
tile = function(source_buf, input_buf, output_buf) ... end,
filename = function(contest, contest_id, problem_id, config, language) ... end,
}
}
<
*cp.Config*
Fields: ~
• {contests} (`table<string,ContestConfig>`) Contest configurations.
• {hooks} (`cp.Hooks`) Hook functions called at various stages.
• {snippets} (`table[]`) LuaSnip snippet definitions.
• {debug} (`boolean`, default: `false`) Show info messages
during operation.
• {tile}? (`function`) Custom window arrangement function.
`function(source_buf, input_buf, output_buf)`
• {filename}? (`function`) Custom filename generation function.
`function(contest, contest_id, problem_id, config, language)`
Should return full filename with extension.
(default: uses problem_id or contest_id)
*cp.ContestConfig*
Fields: ~
• {cpp} (`LanguageConfig`) C++ language configuration.
• {python} (`LanguageConfig`) Python language configuration.
• {default_language} (`string`, default: `"cpp"`) Default language when
`--lang` not specified.
• {timeout_ms} (`number`, default: `2000`) Execution timeout in
milliseconds.
*cp.LanguageConfig*
Fields: ~
• {compile}? (`string[]`) Compile command template with
`{version}`, `{source}`, `{binary}` placeholders.
• {run} (`string[]`) Run command template.
• {debug}? (`string[]`) Debug compile command template.
• {version}? (`number`) Language version (e.g. 20, 23 for C++).
• {extension} (`string`) File extension (e.g. "cc", "py").
• {executable}? (`string`) Executable name for interpreted languages.
*cp.Hooks*
Fields: ~
• {before_run}? (`function`) Called before `:CP run`.
`function(ctx: ProblemContext)`
• {before_debug}? (`function`) Called before `:CP debug`.
`function(ctx: ProblemContext)`
• {setup_code}? (`function`) Called after source file is opened.
Used to configure buffer settings.
`function(ctx: ProblemContext)`
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/abc123/tasks/abc123_a
In terms of cp.nvim, this corresponds to:
- Platform: atcoder
- Contest ID: abc123
- Problem ID: a
Usage examples: >
:CP atcoder abc123 a " Full setup: problem A from contest ABC123
:CP atcoder abc123 " Contest setup: load contest metadata only
:CP b " Switch to problem B (if contest loaded)
:CP next " Navigate to next problem in contest
<
Codeforces ~
*cp-codeforces*
URL format: https://codeforces.com/contest/1234/problem/A
In terms of cp.nvim, this corresponds to:
- Platform: codeforces
- Contest ID: 1234
- Problem ID: a (lowercase)
Usage examples: >
:CP codeforces 1934 a " Full setup: problem A from contest 1934
:CP codeforces 1934 " Contest setup: load contest metadata only
:CP c " Switch to problem C (if contest loaded)
:CP prev " Navigate to previous problem in contest
<
CSES ~
*cp-cses*
URL format: https://cses.fi/problemset/task/1068
CSES is organized by categories rather than contests. Currently all problems
are grouped under "CSES Problem Set" category.
In terms of cp.nvim, this corresponds to:
- Platform: cses
- Contest ID: "CSES Problem Set" (category)
- Problem ID: 1068 (numeric)
Usage examples: >
:CP cses 1068 " Set up problem 1068 from CSES
:CP 1070 " Switch to problem 1070 (if CSES loaded)
:CP next " Navigate to next problem in CSES
<
COMPLETE WORKFLOW EXAMPLE *cp-example*
Example: Setting up and solving AtCoder contest ABC324
1. Browse to https://atcoder.jp/contests/abc324
2. Set up contest and load metadata: >
:CP atcoder abc324
< This caches all problems (A, B, C, D, E, F, G) for navigation
3. Start with problem A: >
:CP a
< This creates a.cc and scrapes test cases
4. Code your solution, then test: >
:CP run
<
5. If test fails, debug individual test cases: >
:CP test
< Navigate with j/k, run specific tests with <enter>
Exit test panel with q or :CP test when done
6. If needed, compile with debug flags: >
:CP debug
<
7. Move to next problem: >
:CP next
< This automatically sets up problem B
7. Continue solving problems with :CP next/:CP prev navigation
8. Submit solutions on AtCoder website
Example: Quick setup for single Codeforces problem >
:CP codeforces 1933 a " One command setup
:CP run " Test immediately
<
TEST PANEL *cp-test*
The test panel provides individual test case debugging for competitive
programming problems, particularly useful for Codeforces where multiple
test cases are combined into single input/output files.
Activation ~
*:CP-test*
:CP test Toggle test panel on/off. When activated,
replaces current layout with test interface.
Toggle again to restore original layout.
Interface ~
The test panel displays a list of test cases with their status and details
for the currently selected test case: >
┌─ Test Cases ───────────────────────────────────────────────┐
│ 1 ✓ PASS 12ms │
│ 2 ✗ FAIL 45ms │
│> 3 ✓ PASS 8ms <-- current selection │
│ 4 ? PENDING │
│ │
│ ── Test 3 ── │
│ Input: │ Expected: │ Actual: │
│ 5 3 │ 8 │ 8 │
│ │ │ │
│ │
│ j/k: navigate <space>: toggle <enter>: run a: run all │
└────────────────────────────────────────────────────────────┘
<
Test Status Indicators ~
✓ PASS Test case passed (green)
✗ FAIL Test case failed (red)
? PENDING Test case not yet executed (yellow)
⟳ RUNNING Test case currently executing (blue)
Keymaps ~
*cp-test-keys*
j / <Down> Navigate to next test case
k / <Up> Navigate to previous test case
<space> Toggle selection of current test case
<enter> Run selected test cases
a Run all test cases
r Re-run failed test cases only
c Clear all test results
q / <esc> Exit test panel (restore layout)
Test Case Sources ~
Test cases are loaded in priority order:
1. Individual scraped test cases (preferred for Codeforces)
2. Combined input/output files from io/ directory (fallback)
For Codeforces problems, the plugin attempts to parse individual test
cases from the scraped contest data, enabling precise debugging of
specific test case failures.
For AtCoder and CSES problems, which typically provide single test
cases, the combined input/output approach is used.
Execution Details ~
Each test case shows:
• Input data provided to your solution
• Expected output from the problem statement
• Actual output produced by your solution
• Execution time in milliseconds
• Error messages (if execution failed)
Test cases are executed individually using the same compilation and
execution pipeline as |:CP-run|, 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 (e.g. a.cc, b.py)
build/
{problem_id}.run " Compiled binary
io/
{problem_id}.cpin " Test input
{problem_id}.cpout " Program output
{problem_id}.expected " Expected output
The plugin automatically manages this structure and navigation between problems
maintains proper file associations.
SNIPPETS *cp-snippets*
cp.nvim integrates with LuaSnip for automatic template expansion. Built-in
snippets include basic C++ and Python templates for each contest type.
Snippet trigger names must EXACTLY match platform names ("codeforces" for
CodeForces, "cses" for CSES, etc.).
Custom snippets can be added via the `snippets` configuration field.
HEALTH CHECK *cp-health*
Run |:checkhealth| cp to verify your setup.
vim:tw=78:ts=8:ft=help:norl: