feat(doc): make docs more concise
This commit is contained in:
parent
3edc3db8aa
commit
0dd145b71e
5 changed files with 58 additions and 196 deletions
3
.github/workflows/quality.yml
vendored
3
.github/workflows/quality.yml
vendored
|
|
@ -27,8 +27,7 @@ jobs:
|
||||||
- 'ftdetect/**'
|
- 'ftdetect/**'
|
||||||
- '*.lua'
|
- '*.lua'
|
||||||
- '.luarc.json'
|
- '.luarc.json'
|
||||||
- 'stylua.toml'
|
- '*.toml'
|
||||||
- 'selene.toml'
|
|
||||||
python:
|
python:
|
||||||
- 'scrapers/**'
|
- 'scrapers/**'
|
||||||
- 'tests/scrapers/**'
|
- 'tests/scrapers/**'
|
||||||
|
|
|
||||||
232
doc/cp.txt
232
doc/cp.txt
|
|
@ -9,8 +9,7 @@ INTRODUCTION *cp* *cp.nvim*
|
||||||
cp.nvim is a competitive programming plugin that automates problem setup,
|
cp.nvim is a competitive programming plugin that automates problem setup,
|
||||||
compilation, and testing workflow for online judges.
|
compilation, and testing workflow for online judges.
|
||||||
|
|
||||||
Supported platforms: AtCoder, Codeforces, CSES
|
Supported platforms (for now!): AtCoder, Codeforces, CSES
|
||||||
Supported languages: C++, Python
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
REQUIREMENTS *cp-requirements*
|
REQUIREMENTS *cp-requirements*
|
||||||
|
|
@ -73,10 +72,7 @@ COMMANDS *cp-commands*
|
||||||
Requires contest setup first.
|
Requires contest setup first.
|
||||||
|
|
||||||
:CP pick Launch configured picker for interactive
|
:CP pick Launch configured picker for interactive
|
||||||
platform/contest/problem selection. Requires
|
platform/contest/problem selection.
|
||||||
picker = 'telescope' or picker = 'fzf-lua'
|
|
||||||
in configuration and corresponding plugin
|
|
||||||
to be installed.
|
|
||||||
|
|
||||||
Navigation Commands ~
|
Navigation Commands ~
|
||||||
:CP next Navigate to next problem in current contest.
|
:CP next Navigate to next problem in current contest.
|
||||||
|
|
@ -123,32 +119,6 @@ Template Variables ~
|
||||||
g++ abc324a.cpp -o build/abc324a.run -std=c++17
|
g++ abc324a.cpp -o build/abc324a.run -std=c++17
|
||||||
<
|
<
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
PICKER INTEGRATION *cp-picker*
|
|
||||||
|
|
||||||
When picker integration is enabled in configuration, cp.nvim provides interactive
|
|
||||||
platform, contest, and problem selection using telescope.nvim or fzf-lua.
|
|
||||||
|
|
||||||
:CP pick *:CP-pick*
|
|
||||||
Launch configured picker for interactive problem selection.
|
|
||||||
Flow: Platform → Contest → Problem → Setup
|
|
||||||
|
|
||||||
Requires picker = 'telescope' or picker = 'fzf-lua' in configuration.
|
|
||||||
Requires corresponding plugin (telescope.nvim or fzf-lua) to be installed.
|
|
||||||
Picker availability is checked at runtime when command is executed.
|
|
||||||
|
|
||||||
Picker Flow ~
|
|
||||||
1. Platform Selection: Choose from AtCoder, Codeforces, CSES
|
|
||||||
2. Contest Selection: Choose from available contests for selected platform
|
|
||||||
3. Problem Selection: Choose from problems in selected contest
|
|
||||||
4. Problem Setup: Automatically runs equivalent of :CP platform contest problem
|
|
||||||
|
|
||||||
Notes ~
|
|
||||||
• Contest lists are fetched dynamically using scrapers
|
|
||||||
• Large contest lists may take time to load
|
|
||||||
• Runtime picker validation - shows clear error if picker plugin not available
|
|
||||||
• Picker configuration can be changed without plugin restart
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
CONFIGURATION *cp-config*
|
CONFIGURATION *cp-config*
|
||||||
|
|
||||||
|
|
@ -176,14 +146,8 @@ Here's an example configuration with lazy.nvim: >lua
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
snippets = {},
|
snippets = {},
|
||||||
hooks = {
|
|
||||||
before_run = nil,
|
|
||||||
before_debug = nil,
|
|
||||||
setup_code = nil,
|
|
||||||
},
|
|
||||||
debug = false,
|
debug = false,
|
||||||
scrapers = { 'atcoder', 'codeforces', 'cses' },
|
scrapers = { 'atcoder', 'codeforces', 'cses' },
|
||||||
filename = default_filename, -- <contest id> + <problem id>
|
|
||||||
run_panel = {
|
run_panel = {
|
||||||
ansi = true,
|
ansi = true,
|
||||||
diff_mode = 'vim',
|
diff_mode = 'vim',
|
||||||
|
|
@ -216,9 +180,7 @@ Here's an example configuration with lazy.nvim: >lua
|
||||||
{diff} (|DiffConfig|) Diff backend configuration.
|
{diff} (|DiffConfig|) Diff backend configuration.
|
||||||
{picker} (string, optional) Picker integration: "telescope",
|
{picker} (string, optional) Picker integration: "telescope",
|
||||||
"fzf-lua", or nil to disable. When enabled, provides
|
"fzf-lua", or nil to disable. When enabled, provides
|
||||||
:Telescope cp or :FzfLua cp commands for interactive
|
:CP pick for interactive platform/contest/problem selection.
|
||||||
platform/contest/problem selection. Requires the
|
|
||||||
corresponding picker plugin to be installed.
|
|
||||||
{filename} (function, optional) Custom filename generation.
|
{filename} (function, optional) Custom filename generation.
|
||||||
function(contest, contest_id, problem_id, config, language)
|
function(contest, contest_id, problem_id, config, language)
|
||||||
Should return full filename with extension.
|
Should return full filename with extension.
|
||||||
|
|
@ -318,21 +280,6 @@ AtCoder ~
|
||||||
*cp-atcoder*
|
*cp-atcoder*
|
||||||
URL format: https://atcoder.jp/contests/abc123/tasks/abc123_a
|
URL format: https://atcoder.jp/contests/abc123/tasks/abc123_a
|
||||||
|
|
||||||
AtCoder contests use consistent naming patterns where contest ID and problem
|
|
||||||
ID are combined to form the task name.
|
|
||||||
|
|
||||||
Platform characteristics:
|
|
||||||
• Contest types: ABC (Beginner), ARC (Regular), AGC (Grand), etc.
|
|
||||||
• Problem naming: Contest ID + problem letter (e.g. "abc324_a")
|
|
||||||
• Multi-test problems: Handled with conditional compilation directives
|
|
||||||
• Template features: Includes fast I/O and common competitive programming
|
|
||||||
headers
|
|
||||||
|
|
||||||
In terms of cp.nvim, this corresponds to:
|
|
||||||
- Platform: atcoder
|
|
||||||
- Contest ID: abc123 (from URL path segment)
|
|
||||||
- Problem ID: a (single letter, extracted from task name)
|
|
||||||
|
|
||||||
Usage examples: >
|
Usage examples: >
|
||||||
:CP atcoder abc324 a " Full setup: problem A from contest ABC324
|
:CP atcoder abc324 a " Full setup: problem A from contest ABC324
|
||||||
:CP atcoder abc324 " Contest setup: load contest metadata only
|
:CP atcoder abc324 " Contest setup: load contest metadata only
|
||||||
|
|
@ -347,21 +294,6 @@ Codeforces ~
|
||||||
*cp-codeforces*
|
*cp-codeforces*
|
||||||
URL format: https://codeforces.com/contest/1234/problem/A
|
URL format: https://codeforces.com/contest/1234/problem/A
|
||||||
|
|
||||||
Codeforces uses numeric contest IDs with letter-based problem identifiers.
|
|
||||||
Educational rounds, gym contests, and regular contests all follow this pattern.
|
|
||||||
|
|
||||||
Platform characteristics:
|
|
||||||
• Contest types: Regular, Educational, Div. 1/2/3, Global rounds
|
|
||||||
• Problem naming: Numeric contest + problem letter
|
|
||||||
• Multi-test support: Template includes test case loop structure
|
|
||||||
• Interactive problems: Supported with flush handling
|
|
||||||
• Time/memory limits: Typically 1-2 seconds, 256 MB
|
|
||||||
|
|
||||||
In terms of cp.nvim, this corresponds to:
|
|
||||||
- Platform: codeforces
|
|
||||||
- Contest ID: 1234 (numeric, from URL)
|
|
||||||
- Problem ID: a (lowercase letter, normalized from URL)
|
|
||||||
|
|
||||||
Usage examples: >
|
Usage examples: >
|
||||||
:CP codeforces 1934 a " Full setup: problem A from contest 1934
|
:CP codeforces 1934 a " Full setup: problem A from contest 1934
|
||||||
:CP codeforces 1934 " Contest setup: load contest metadata only
|
:CP codeforces 1934 " Contest setup: load contest metadata only
|
||||||
|
|
@ -375,21 +307,6 @@ CSES ~
|
||||||
*cp-cses*
|
*cp-cses*
|
||||||
URL format: https://cses.fi/problemset/task/1068
|
URL format: https://cses.fi/problemset/task/1068
|
||||||
|
|
||||||
CSES (Code Submission Evaluation System) is organized by problem categories
|
|
||||||
rather than traditional contests. Problems are grouped by topic and difficulty.
|
|
||||||
|
|
||||||
Platform characteristics:
|
|
||||||
• Organization: Category-based (Introductory, Sorting, Dynamic Programming)
|
|
||||||
• Problem numbering: Sequential numeric IDs (1001, 1068, etc.)
|
|
||||||
• Difficulty progression: Problems increase in complexity within categories
|
|
||||||
• No time pressure: Educational focus rather than contest environment
|
|
||||||
• Cache expiry: 30 days (problems may be updated periodically)
|
|
||||||
|
|
||||||
In terms of cp.nvim, this corresponds to:
|
|
||||||
- Platform: cses
|
|
||||||
- Contest ID: Category name (introductory_problems, sorting_and_searching)
|
|
||||||
- Problem ID: Problem number (1068, 1640)
|
|
||||||
|
|
||||||
Usage examples: >
|
Usage examples: >
|
||||||
:CP cses dynamic_programming 1633 " Set up problem 1633 from DP category
|
:CP cses dynamic_programming 1633 " Set up problem 1633 from DP category
|
||||||
:CP cses dynamic_programming " Set up ALL problems from DP category
|
:CP cses dynamic_programming " Set up ALL problems from DP category
|
||||||
|
|
@ -437,6 +354,39 @@ Example: Setting up and solving AtCoder contest ABC324
|
||||||
|
|
||||||
9. Submit solutions on AtCoder website
|
9. Submit solutions on AtCoder website
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
PICKER INTEGRATION *cp-picker*
|
||||||
|
|
||||||
|
When picker integration is enabled in configuration, cp.nvim provides interactive
|
||||||
|
platform, contest, and problem selection using telescope.nvim or fzf-lua.
|
||||||
|
|
||||||
|
:CP pick *:CP-pick*
|
||||||
|
Launch configured picker for interactive problem selection.
|
||||||
|
Control Flow: Select Platform → Contest → Problem → Code!
|
||||||
|
|
||||||
|
Requires picker = 'telescope' or picker = 'fzf-lua' in configuration.
|
||||||
|
Requires corresponding plugin (telescope.nvim or fzf-lua) to be installed.
|
||||||
|
|
||||||
|
Picker Controls ~
|
||||||
|
*cp-picker-controls*
|
||||||
|
The picker interface provides several keyboard shortcuts for enhanced control:
|
||||||
|
|
||||||
|
<c-r> Force refresh contest list, bypassing cache
|
||||||
|
Useful when contest lists are outdated or incomplete
|
||||||
|
Shows loading indicator during refresh operation
|
||||||
|
|
||||||
|
Standard picker controls (telescope.nvim/fzf-lua):
|
||||||
|
<cr> Select current item and proceed to next step
|
||||||
|
<c-c> / <esc> Cancel picker and return to editor
|
||||||
|
<c-n> / <down> Navigate to next item
|
||||||
|
<c-p> / <up> Navigate to previous item
|
||||||
|
/ Start filtering/searching items
|
||||||
|
|
||||||
|
Notes ~
|
||||||
|
• Contest lists are fetched dynamically using scrapers with a TTL of 1 day
|
||||||
|
• Use <c-r> to force refresh
|
||||||
|
• Large contest lists may take time to load
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
RUN PANEL *cp-run*
|
RUN PANEL *cp-run*
|
||||||
|
|
||||||
|
|
@ -559,11 +509,10 @@ ANSI colors automatically use your terminal's color palette through Neovim's
|
||||||
vim.g.terminal_color_* variables. This ensures compiler colors match your
|
vim.g.terminal_color_* variables. This ensures compiler colors match your
|
||||||
colorscheme without manual configuration.
|
colorscheme without manual configuration.
|
||||||
|
|
||||||
If your colorscheme doesn't set terminal colors, cp.nvim falls back to
|
If your colorscheme doesn't set terminal colors, cp.nvim will warn you and
|
||||||
sensible defaults. You can override terminal colors in your configuration: >vim
|
ANSI colors won't display properly - set them like so: >vim
|
||||||
let g:terminal_color_1 = '#ff6b6b' " Custom red
|
let g:terminal_color_1 = '#ff6b6b'
|
||||||
let g:terminal_color_2 = '#51cf66' " Custom green
|
...
|
||||||
<
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
HIGHLIGHT CUSTOMIZATION *cp-highlight-custom*
|
HIGHLIGHT CUSTOMIZATION *cp-highlight-custom*
|
||||||
|
|
@ -630,97 +579,6 @@ cp.nvim creates the following file structure upon problem setup: >
|
||||||
{problem_id}.n.cpout " nth program output
|
{problem_id}.n.cpout " nth program output
|
||||||
{problem_id}.expected " Expected output
|
{problem_id}.expected " Expected output
|
||||||
<
|
<
|
||||||
|
|
||||||
The plugin automatically manages this structure and navigation between problems
|
|
||||||
maintains proper file associations.
|
|
||||||
|
|
||||||
==============================================================================
|
|
||||||
CACHING SYSTEM *cp-caching*
|
|
||||||
|
|
||||||
cp.nvim maintains a persistent cache to improve performance and enable offline
|
|
||||||
functionality. The cache stores contest metadata, problem lists, test cases,
|
|
||||||
and file-to-context mappings.
|
|
||||||
|
|
||||||
Cache Location ~
|
|
||||||
*cp-cache-location*
|
|
||||||
Cache is stored at: >
|
|
||||||
vim.fn.stdpath('data') .. '/cp-nvim.json'
|
|
||||||
<
|
|
||||||
Cache Structure ~
|
|
||||||
*cp-cache-structure*
|
|
||||||
The cache contains four main sections:
|
|
||||||
|
|
||||||
contest_data Contest metadata and problem lists
|
|
||||||
• Indexed by: `platform:contest_id`
|
|
||||||
• Contains: Problem names, IDs, URLs, constraints
|
|
||||||
• Expiry: Platform-dependent (see |cp-cache-expiry|)
|
|
||||||
|
|
||||||
test_cases Scraped test case input/output pairs
|
|
||||||
• Indexed by: `platform:contest_id:problem_id`
|
|
||||||
• Contains: Input data, expected output, test case count
|
|
||||||
• Expiry: Never (local test data persists)
|
|
||||||
|
|
||||||
file_states File-to-context mapping
|
|
||||||
• Indexed by: Absolute file path
|
|
||||||
• Contains: Platform, contest_id, problem_id, language
|
|
||||||
• Purpose: Enables context restoration with `:CP`
|
|
||||||
|
|
||||||
timestamps Last update times for cache validation
|
|
||||||
• Tracks: When each cache entry was last refreshed
|
|
||||||
• Used for: Expiry checking and incremental updates
|
|
||||||
|
|
||||||
Cache Expiry Policy ~
|
|
||||||
*cp-cache-expiry*
|
|
||||||
Different data types have different expiry policies:
|
|
||||||
|
|
||||||
AtCoder/Codeforces contest data Never expires (contests are immutable)
|
|
||||||
CSES problem data 30 days (problems may be updated)
|
|
||||||
Test cases Never expires (local test data)
|
|
||||||
File states Never expires (tracks user workspace)
|
|
||||||
|
|
||||||
Manual Cache Management ~
|
|
||||||
*cp-cache-management*
|
|
||||||
While cache management is automatic, you can manually intervene:
|
|
||||||
|
|
||||||
Clear specific contest cache: >
|
|
||||||
:lua require('cp.cache').clear_contest('atcoder', 'abc324')
|
|
||||||
<
|
|
||||||
Clear all cache data: >
|
|
||||||
:lua require('cp.cache').clear_all()
|
|
||||||
<
|
|
||||||
Force refresh contest metadata: >
|
|
||||||
:lua require('cp.cache').refresh_contest('codeforces', '1934')
|
|
||||||
<
|
|
||||||
View cache statistics: >
|
|
||||||
:lua print(vim.inspect(require('cp.cache').get_stats()))
|
|
||||||
<
|
|
||||||
Note: Manual cache operations require Lua
|
|
||||||
knowledge and are primarily for debugging.
|
|
||||||
|
|
||||||
Offline Functionality ~
|
|
||||||
*cp-cache-offline*
|
|
||||||
The cache enables limited offline functionality:
|
|
||||||
|
|
||||||
✓ Restore context from cached file states
|
|
||||||
✓ Navigate between cached problems in a contest
|
|
||||||
✓ Access cached test cases for local development
|
|
||||||
✓ Use cached templates and configuration
|
|
||||||
|
|
||||||
✗ Scrape new problems without internet connection
|
|
||||||
✗ Download new contest metadata
|
|
||||||
✗ Update problem constraints or test cases
|
|
||||||
|
|
||||||
Performance Considerations ~
|
|
||||||
*cp-cache-performance*
|
|
||||||
The cache provides several performance benefits:
|
|
||||||
|
|
||||||
• Instant context restoration: No network requests needed
|
|
||||||
• Fast problem navigation: Problem lists loaded from cache
|
|
||||||
• Reduced scraping: Test cases cached after first download
|
|
||||||
• Batch operations: Multiple problems can be set up quickly
|
|
||||||
|
|
||||||
Cache size typically remains under 1MB even with extensive usage.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
SNIPPETS *cp-snippets*
|
SNIPPETS *cp-snippets*
|
||||||
|
|
||||||
|
|
@ -729,7 +587,15 @@ snippets include basic C++ and Python templates for each contest type.
|
||||||
|
|
||||||
Snippet trigger names must match the following format exactly: >
|
Snippet trigger names must match the following format exactly: >
|
||||||
|
|
||||||
cp.nvim/{platform}
|
cp.nvim/{platform}.{language}
|
||||||
|
<
|
||||||
|
Where {platform} is the contest platform (atcoder, codeforces, cses) and
|
||||||
|
{language} is the programming language (cpp, python).
|
||||||
|
|
||||||
|
Examples: >
|
||||||
|
cp.nvim/atcoder.cpp
|
||||||
|
cp.nvim/codeforces.python
|
||||||
|
cp.nvim/cses.cpp
|
||||||
<
|
<
|
||||||
|
|
||||||
Custom snippets can be added via the `snippets` configuration field.
|
Custom snippets can be added via the `snippets` configuration field.
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,6 @@ def scrape_contest_problems(contest_id: str) -> list[ProblemSummary]:
|
||||||
if problem:
|
if problem:
|
||||||
problems.append(problem)
|
problems.append(problem)
|
||||||
|
|
||||||
problems.sort(key=lambda x: x.id)
|
|
||||||
return problems
|
return problems
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ def scrape_contest_problems(contest_id: str) -> list[ProblemSummary]:
|
||||||
ProblemSummary(id=problem_letter, name=problem_name)
|
ProblemSummary(id=problem_letter, name=problem_name)
|
||||||
)
|
)
|
||||||
|
|
||||||
problems.sort(key=lambda x: x.id)
|
# Preserve contest order - do not sort
|
||||||
|
|
||||||
seen: set[str] = set()
|
seen: set[str] = set()
|
||||||
unique_problems: list[ProblemSummary] = []
|
unique_problems: list[ProblemSummary] = []
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,6 @@ def scrape_category_problems(category_id: str) -> list[ProblemSummary]:
|
||||||
|
|
||||||
problems.append(ProblemSummary(id=problem_id, name=problem_name))
|
problems.append(ProblemSummary(id=problem_id, name=problem_name))
|
||||||
|
|
||||||
problems.sort(key=lambda x: int(x.id))
|
|
||||||
return problems
|
return problems
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
@ -263,8 +262,7 @@ def scrape_all_problems() -> dict[str, list[ProblemSummary]]:
|
||||||
problem = ProblemSummary(id=problem_id, name=problem_name)
|
problem = ProblemSummary(id=problem_id, name=problem_name)
|
||||||
all_categories[current_category].append(problem)
|
all_categories[current_category].append(problem)
|
||||||
|
|
||||||
for category in all_categories:
|
# Preserve HTML document order - do not sort
|
||||||
all_categories[category].sort(key=lambda x: int(x.id))
|
|
||||||
|
|
||||||
print(
|
print(
|
||||||
f"Found {len(all_categories)} categories with {sum(len(probs) for probs in all_categories.values())} problems",
|
f"Found {len(all_categories)} categories with {sum(len(probs) for probs in all_categories.values())} problems",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue