*cp.txt* Competitive programming plugin for Neovim Author: Barrett Ruth 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 diff Enter diff mode to compare actual vs expected output. Run again to exit diff mode. 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`) 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 needed, debug: > :CP debug < 6. Compare output visually: > :CP diff < 7. Move to next problem: > :CP next < This automatically sets up problem B 8. Continue solving problems with :CP next/:CP prev navigation 9. Submit solutions on AtCoder website Example: Quick setup for single Codeforces problem > :CP codeforces 1933 a " One command setup :CP run " Test immediately < 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: