225 lines
7.4 KiB
Text
225 lines
7.4 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
|
|
|
|
REQUIREMENTS *cp-requirements*
|
|
|
|
- Neovim 0.10.0+
|
|
- uv package manager (https://docs.astral.sh/uv/)
|
|
- C++ compiler (g++/clang++)
|
|
|
|
Optional:
|
|
- LuaSnip for template expansion (https://github.com/L3MON4D3/LuaSnip)
|
|
|
|
COMMANDS *cp-commands*
|
|
|
|
*:CP*
|
|
:CP {contest} Set up contest environment for {contest}.
|
|
Available contests: atcoder, codeforces, cses
|
|
|
|
:CP {contest} {contest_id} {problem_letter?}
|
|
Set up problem from {contest}. Extract contest_id
|
|
and problem_letter (optional) from the problem URL.
|
|
Scrapes test cases and creates source file.
|
|
|
|
:CP {contest_id} {problem_letter}
|
|
Set up problem in current contest mode.
|
|
Requires contest to be set first with :CP {contest}
|
|
|
|
: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.
|
|
|
|
CONFIGURATION *cp-config*
|
|
|
|
cp.nvim is automatically lazy-loaded - no config/setup is required.
|
|
|
|
Provide extra options via a setup() function with your package manager. For
|
|
example, with lazy.nvim (https://github.com/folke/lazy.nvim):
|
|
|
|
{
|
|
'barrett-ruth/cp.nvim',
|
|
config = function()
|
|
local ls = require('luasnip')
|
|
local s = ls.snippet
|
|
|
|
require('cp').setup({
|
|
debug = false,
|
|
contests = {
|
|
default = {
|
|
cpp_version = 20,
|
|
compile_flags = { "-O2", "-DLOCAL", "-Wall", "-Wextra" },
|
|
debug_flags = { "-g3", "-fsanitize=address,undefined", "-DLOCAL" },
|
|
timeout_ms = 2000,
|
|
},
|
|
atcoder = {
|
|
cpp_version = 23,
|
|
},
|
|
},
|
|
snippets = {
|
|
cses = {
|
|
s("cses", "#include <iostream>\nusing namespace std;\n\nint main() {\n\t$0\n}")
|
|
},
|
|
},
|
|
hooks = {
|
|
before_run = function(problem_id)
|
|
vim.cmd.w()
|
|
vim.lsp.buf.format()
|
|
end,
|
|
before_debug = function(problem_id)
|
|
...
|
|
end
|
|
},
|
|
tile = function(source_buf, input_buf, output_buf)
|
|
vim.api.nvim_set_current_buf(source_buf)
|
|
vim.cmd.vsplit()
|
|
vim.api.nvim_set_current_buf(output_buf)
|
|
vim.cmd.vsplit()
|
|
vim.api.nvim_set_current_buf(input_buf)
|
|
vim.cmd('wincmd h | wincmd h')
|
|
end,
|
|
filename = function(contest, problem_id, problem_letter)
|
|
if contest == "atcoder" then
|
|
return problem_id:lower() .. (problem_letter or "") .. ".cpp"
|
|
else
|
|
return problem_id:lower() .. (problem_letter or "") .. ".cc"
|
|
end
|
|
end,
|
|
})
|
|
end
|
|
}
|
|
|
|
Configuration options:
|
|
|
|
contests Dictionary of contest configurations - each contest inherits from 'default'.
|
|
|
|
cpp_version c++ standard version (e.g. 20, 23)
|
|
compile_flags compiler flags for run builds
|
|
debug_flags compiler flags for debug builds
|
|
timeout_ms duration (ms) to run/debug before timeout
|
|
|
|
snippets LuaSnip snippets by contest type
|
|
|
|
hooks Functions called at specific events
|
|
before_run Called before :CP run
|
|
function(problem_id)
|
|
(default: nil, do nothing)
|
|
before_debug Called before :CP debug
|
|
function(problem_id)
|
|
(default: nil, do nothing)
|
|
|
|
debug Show info messages during operation
|
|
(default: false, silent operation)
|
|
|
|
tile Custom function to arrange windows
|
|
function(source_buf, input_buf, output_buf)
|
|
(default: nil, uses built-in layout)
|
|
|
|
filename Custom function to generate filenames
|
|
function(contest, problem_id, problem_letter)
|
|
(default: nil, uses problem_id + letter + ".cc")
|
|
|
|
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:
|
|
|
|
- Contest ID: abc123
|
|
- Problem letter: a
|
|
|
|
Usage examples: >
|
|
:CP atcoder abc123 a " Set up problem A from contest ABC123
|
|
:CP atcoder " Set up AtCoder contest mode first
|
|
:CP abc123 a " Then set up problem (if contest mode is set)
|
|
<
|
|
Codeforces ~
|
|
*cp-codeforces*
|
|
URL format: https://codeforces.com/contest/1234/problem/A
|
|
|
|
In terms of cp.nvim, this corresponds to:
|
|
|
|
- Contest ID: 1234
|
|
- Problem letter: A
|
|
|
|
Usage examples: >
|
|
:CP codeforces 1234 a " Set up problem A from contest id 1234
|
|
:CP codeforces " Set up Codeforces contest mode first
|
|
:CP 1234 a " Then set up problem (if contest mode is set)
|
|
<
|
|
CSES ~
|
|
*cp-cses*
|
|
URL format: https://cses.fi/problemset/task/1068
|
|
|
|
In terms of cp.nvim, this corresponds to:
|
|
- Problem ID: 1068
|
|
|
|
Usage examples: >
|
|
:CP cses 1068 " Set up problem 1068
|
|
:CP cses " Set up CSES contest mode first
|
|
:CP 1068 " Then set up problem (if contest mode is set)
|
|
<
|
|
COMPLETE WORKFLOW EXAMPLE *cp-example*
|
|
|
|
Example: Setting up AtCoder problem ABC123-A
|
|
|
|
1. Browse to https://atcoder.jp/contests/abc123/tasks/abc123_a
|
|
2. Read the problem statement on the website
|
|
3. In Neovim, extract identifiers and set up
|
|
:CP atcoder abc123 a
|
|
<
|
|
This creates abc123a.cc (or however you've configured the filename in
|
|
*cp-setup*) and scrapes test cases
|
|
4. Code and test
|
|
:CP run
|
|
5. Debug
|
|
:CP debug
|
|
6. Test: >
|
|
:CP diff
|
|
7. Submit remote on AtCoder
|
|
|
|
FILE STRUCTURE *cp-files*
|
|
|
|
cp.nvim creates the following file structure upon setup:
|
|
|
|
problem.cc
|
|
build/*.{run,debug}
|
|
io/
|
|
problem.in
|
|
problem.out
|
|
problem.expected
|
|
|
|
SNIPPETS *cp-snippets*
|
|
|
|
cp.nvim integrates with LuaSnip for automatic template expansion. When you
|
|
open a new problem file, type the contest name and press <Tab> to expand.
|
|
|
|
Built-in snippets include basic C++ templates for each contest type.
|
|
Custom snippets can be added via configuration.
|
|
|
|
HEALTH CHECK *cp-health*
|
|
|
|
Run |:checkhealth| cp to verify your setup.
|
|
|
|
vim:tw=78:ts=8:ft=help:norl:
|