## Problem Language version coverage was incomplete across all platforms, AtCoder submit used a stale cookie fast-path that caused silent failures, and raw `vim.notify` calls throughout the codebase produced inconsistent or missing `[cp.nvim]:` prefixes. ## Solution Remove cookie persistence from AtCoder login/submit (always fresh login), increase the submit nav timeout to 40s, and switch to in-memory buffer upload with the correct per-language extension from a full `_LANGUAGE_ID_EXTENSION` map covering all 116 AtCoder languages. Expand `LANGUAGE_VERSIONS` in `constants.lua` with all AtCoder languages, 15 new CF languages with full version variants, and 50+ Kattis languages. Fix AtCoder `prolog` ID (`6079`→`6081`, was Pony) and remove the non-existent `racket` entry. Replace all raw `vim.notify` calls with `logger.log`. Simplify the submit language doc to point at `constants.lua` rather than maintaining a static table.
1343 lines
59 KiB
Text
1343 lines
59 KiB
Text
*cp.nvim.txt* Competitive programming plugin for Neovim
|
||
|
||
Author: Barrett Ruth <br.barrettruth@gmail.com>
|
||
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 = '<c-n>', -- or nil to disable
|
||
prev_test_key = '<c-p>', -- 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<string,|CpLanguage|>) Global language registry.
|
||
Each language provides an {extension} and {commands}.
|
||
{platforms} (table<string,|CpPlatform||false>) 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<string,|CpPlatformOverrides|>, 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: '<c-n>') Keymap to navigate
|
||
to next test in I/O view. Set to nil to disable.
|
||
{prev_test_key} (string|nil, default: '<c-p>') 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/<name>.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
|
||
<c-w> 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/<name>.run
|
||
• Debug build: commands.debug → outputs to build/<name>.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 <Plug> mappings for all primary actions. These dispatch
|
||
through the same code path as |:CP|.
|
||
|
||
*<Plug>(cp-run)*
|
||
<Plug>(cp-run) Run tests in I/O view. Equivalent to :CP run.
|
||
|
||
*<Plug>(cp-panel)*
|
||
<Plug>(cp-panel) Open full-screen test panel. Equivalent to :CP panel.
|
||
|
||
*<Plug>(cp-edit)*
|
||
<Plug>(cp-edit) Open the test case editor. Equivalent to :CP edit.
|
||
|
||
*<Plug>(cp-next)*
|
||
<Plug>(cp-next) Navigate to the next problem. Equivalent to :CP next.
|
||
|
||
*<Plug>(cp-prev)*
|
||
<Plug>(cp-prev) Navigate to the previous problem. Equivalent to :CP prev.
|
||
|
||
*<Plug>(cp-pick)*
|
||
<Plug>(cp-pick) Launch the contest picker. Equivalent to :CP pick.
|
||
|
||
*<Plug>(cp-interact)*
|
||
<Plug>(cp-interact) Open interactive mode. Equivalent to :CP interact.
|
||
|
||
*<Plug>(cp-stress)*
|
||
<Plug>(cp-stress) Run stress test loop. Equivalent to :CP stress.
|
||
|
||
*<Plug>(cp-submit)*
|
||
<Plug>(cp-submit) Submit current solution. Equivalent to :CP submit.
|
||
|
||
*<Plug>(cp-open)*
|
||
<Plug>(cp-open) Open current problem URL in browser. Equivalent to :CP open.
|
||
|
||
Example configuration: >lua
|
||
vim.keymap.set('n', '<leader>cr', '<Plug>(cp-run)')
|
||
vim.keymap.set('n', '<leader>cp', '<Plug>(cp-panel)')
|
||
vim.keymap.set('n', '<leader>ce', '<Plug>(cp-edit)')
|
||
vim.keymap.set('n', '<leader>cn', '<Plug>(cp-next)')
|
||
vim.keymap.set('n', '<leader>cN', '<Plug>(cp-prev)')
|
||
vim.keymap.set('n', '<leader>cc', '<Plug>(cp-pick)')
|
||
vim.keymap.set('n', '<leader>ci', '<Plug>(cp-interact)')
|
||
vim.keymap.set('n', '<leader>cs', '<Plug>(cp-stress)')
|
||
vim.keymap.set('n', '<leader>cu', '<Plug>(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 <c-n>/<c-p>, 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:
|
||
<c-n> Next test (default, see |RunConfig|.next_test_key)
|
||
<c-p> 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*
|
||
<c-r> 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 ~
|
||
<c-q> 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 ~
|
||
<c-q> 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 ~
|
||
|
||
Each platform supports all of its own languages and compiler versions.
|
||
The full list of version keys is in `lua/cp/constants.lua` under
|
||
`LANGUAGE_VERSIONS`. Use any key from that table as the {version} value.
|
||
|
||
To bypass version lookup entirely, set {submit_id} to the raw platform
|
||
language ID (the value from the platform's submit page dropdown):
|
||
>lua
|
||
platforms = {
|
||
codeforces = {
|
||
overrides = { cpp = { submit_id = "91" } },
|
||
},
|
||
},
|
||
<
|
||
|
||
==============================================================================
|
||
OPEN *cp-open*
|
||
|
||
Open a platform URL for the current contest in the browser.
|
||
|
||
:CP open [problem|contest|standings]
|
||
Open the URL for the active problem, contest page, or standings.
|
||
Defaults to "problem" if no argument is given. Uses |vim.ui.open|.
|
||
Warns if the URL is unavailable (e.g. CSES has no standings page).
|
||
|
||
Platform support:
|
||
AtCoder problem, contest, standings
|
||
Codeforces problem, contest, standings
|
||
CSES problem, contest (no standings)
|
||
Others Not yet implemented.
|
||
|
||
==============================================================================
|
||
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
|
||
|
||
==============================================================================
|
||
STATUSLINE INTEGRATION *cp-statusline*
|
||
|
||
cp.nvim exposes its runtime state through a public module that can be queried
|
||
from any statusline plugin. Import it with: >lua
|
||
local state = require('cp.state')
|
||
<
|
||
All getters return nil when no problem is active, so guard every value before
|
||
use. Calling any getter outside a CP context is safe and has no side effects.
|
||
|
||
State API ~
|
||
*cp.State*
|
||
The following getters are available for statusline use:
|
||
|
||
get_platform() (string?) Platform id. e.g. "codeforces", "atcoder"
|
||
get_contest_id() (string?) Contest id. e.g. "1933", "abc324"
|
||
get_problem_id() (string?) Problem id. e.g. "A", "B"
|
||
get_language() (string?) Language id. e.g. "cpp", "python"
|
||
get_base_name() (string?) Derived filename stem. e.g. "1933a"
|
||
get_source_file() (string?) Full source filename. e.g. "1933a.cc"
|
||
get_active_panel() (string?) One of 'run', 'interactive', 'stress', or
|
||
nil when no panel is open.
|
||
|
||
Race API ~
|
||
*cp-race-status*
|
||
require('cp.race').status() returns a table describing the race state:
|
||
{ active = false }
|
||
{ active = true, platform = string, contest_id = string,
|
||
remaining_seconds = number }
|
||
|
||
Recipe: vanilla statusline ~
|
||
|
||
Set vim.o.statusline from an autocommand so it is recalculated on every
|
||
BufEnter: >lua
|
||
local function cp_component()
|
||
local state = require('cp.state')
|
||
local platform = state.get_platform()
|
||
if not platform then
|
||
return ''
|
||
end
|
||
local parts = {
|
||
platform,
|
||
state.get_contest_id(),
|
||
state.get_problem_id(),
|
||
state.get_language(),
|
||
}
|
||
local filtered = {}
|
||
for _, v in ipairs(parts) do
|
||
if v then filtered[#filtered + 1] = v end
|
||
end
|
||
return '[' .. table.concat(filtered, ' · ') .. ']'
|
||
end
|
||
|
||
vim.api.nvim_create_autocmd({ 'BufEnter', 'User' }, {
|
||
callback = function()
|
||
vim.o.statusline = cp_component() .. ' %f %=%l:%c'
|
||
end
|
||
})
|
||
<
|
||
|
||
Recipe: lualine ~
|
||
|
||
Add a custom component to any lualine section. The cond field hides the
|
||
component entirely when no problem is active: >lua
|
||
local function cp_lualine()
|
||
local state = require('cp.state')
|
||
local parts = {
|
||
state.get_platform(),
|
||
state.get_contest_id(),
|
||
state.get_problem_id(),
|
||
state.get_language(),
|
||
}
|
||
local filtered = {}
|
||
for _, v in ipairs(parts) do
|
||
if v then filtered[#filtered + 1] = v end
|
||
end
|
||
return table.concat(filtered, ' · ')
|
||
end
|
||
|
||
require('lualine').setup({
|
||
sections = {
|
||
lualine_c = {
|
||
{
|
||
cp_lualine,
|
||
cond = function()
|
||
return require('cp.state').get_platform() ~= nil
|
||
end,
|
||
},
|
||
},
|
||
},
|
||
})
|
||
<
|
||
|
||
Recipe: heirline ~
|
||
|
||
Build a heirline component using a provider and condition: >lua
|
||
local CpComponent = {
|
||
condition = function()
|
||
return require('cp.state').get_platform() ~= nil
|
||
end,
|
||
provider = function()
|
||
local state = require('cp.state')
|
||
local parts = {
|
||
state.get_platform(),
|
||
state.get_contest_id(),
|
||
state.get_problem_id(),
|
||
state.get_language(),
|
||
}
|
||
local filtered = {}
|
||
for _, v in ipairs(parts) do
|
||
if v then filtered[#filtered + 1] = v end
|
||
end
|
||
return '[' .. table.concat(filtered, ' · ') .. ']'
|
||
end,
|
||
}
|
||
<
|
||
Include CpComponent in your heirline StatusLine spec wherever desired.
|
||
|
||
==============================================================================
|
||
PANEL KEYMAPS *cp-panel-keys*
|
||
|
||
<c-n> Navigate to next test case
|
||
<c-p> Navigate to previous test case
|
||
t Cycle through configured diff modes (see |cp.PanelConfig|)
|
||
q Exit panel and restore layout
|
||
<c-q> 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:
|