feat: remove default contest
This commit is contained in:
parent
d5395b20ab
commit
b679e2b932
5 changed files with 81 additions and 134 deletions
110
doc/cp.txt
110
doc/cp.txt
|
|
@ -107,6 +107,11 @@ Optional configuration with lazy.nvim: >
|
||||||
-- ctx.problem_id, ctx.platform, ctx.source_file, etc.
|
-- ctx.problem_id, ctx.platform, ctx.source_file, etc.
|
||||||
vim.cmd.w()
|
vim.cmd.w()
|
||||||
end,
|
end,
|
||||||
|
setup_code = function(ctx)
|
||||||
|
vim.wo.foldmethod = "marker"
|
||||||
|
vim.wo.foldmarker = "{{{,}}}"
|
||||||
|
vim.diagnostic.enable(false)
|
||||||
|
end,
|
||||||
},
|
},
|
||||||
snippets = { ... }, -- LuaSnip snippets
|
snippets = { ... }, -- LuaSnip snippets
|
||||||
tile = function(source_buf, input_buf, output_buf) ... end,
|
tile = function(source_buf, input_buf, output_buf) ... end,
|
||||||
|
|
@ -115,56 +120,63 @@ Optional configuration with lazy.nvim: >
|
||||||
}
|
}
|
||||||
<
|
<
|
||||||
|
|
||||||
Configuration options:
|
*cp.Config*
|
||||||
|
|
||||||
contests Dictionary of contest configurations - each contest inherits from 'default'.
|
Fields: ~
|
||||||
|
• {contests} (`table<string,ContestConfig>`) Contest configurations.
|
||||||
|
Each contest inherits from 'default'.
|
||||||
|
• {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, problem_id, problem_letter)`
|
||||||
|
|
||||||
cpp C++ language configuration
|
*cp.ContestConfig*
|
||||||
compile Compile command template with {version}, {source}, {binary} placeholders
|
|
||||||
run Run command template with {binary} placeholder
|
|
||||||
debug Debug compile command template
|
|
||||||
version C++ standard version (e.g. 20, 23)
|
|
||||||
extension File extension for C++ files (default: "cc")
|
|
||||||
|
|
||||||
python Python language configuration
|
Fields: ~
|
||||||
run Run command template with {source} placeholder
|
• {cpp} (`LanguageConfig`) C++ language configuration.
|
||||||
debug Debug run command template
|
• {python} (`LanguageConfig`) Python language configuration.
|
||||||
extension File extension for Python files (default: "py")
|
• {default_language} (`string`, default: `"cpp"`) Default language when
|
||||||
|
`--lang` not specified.
|
||||||
|
• {timeout_ms} (`number`, default: `2000`) Execution timeout in
|
||||||
|
milliseconds.
|
||||||
|
|
||||||
default_language Default language when --lang not specified (default: "cpp")
|
*cp.LanguageConfig*
|
||||||
|
|
||||||
timeout_ms Duration (ms) to run/debug before timeout
|
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.
|
||||||
|
|
||||||
snippets LuaSnip snippets by contest type
|
*cp.Hooks*
|
||||||
|
|
||||||
hooks Functions called at specific events
|
Fields: ~
|
||||||
before_run Called before :CP run
|
• {before_run}? (`function`) Called before `:CP run`.
|
||||||
function(ctx)
|
`function(ctx: HookContext)`
|
||||||
ctx contains:
|
• {before_debug}? (`function`) Called before `:CP debug`.
|
||||||
- problem_id: string
|
`function(ctx: HookContext)`
|
||||||
- platform: string (atcoder/codeforces/cses)
|
• {setup_code}? (`function`) Called after source file is opened.
|
||||||
- contest_id: string
|
Used to configure buffer settings.
|
||||||
- source_file: string (path to source)
|
`function(ctx: HookContext)`
|
||||||
- input_file: string (path to .cpin)
|
|
||||||
- output_file: string (path to .cpout)
|
|
||||||
- expected_file: string (path to .expected)
|
|
||||||
- contest_config: table (language configs)
|
|
||||||
(default: nil, do nothing)
|
|
||||||
before_debug Called before :CP debug
|
|
||||||
function(ctx)
|
|
||||||
Same ctx as before_run
|
|
||||||
(default: nil, do nothing)
|
|
||||||
|
|
||||||
debug Show info messages during operation
|
*cp.HookContext*
|
||||||
(default: false, silent operation)
|
|
||||||
|
|
||||||
tile Custom function to arrange windows
|
Fields: ~
|
||||||
function(source_buf, input_buf, output_buf)
|
• {problem_id} (`string`) Problem identifier (e.g. "a", "b").
|
||||||
(default: nil, uses built-in layout)
|
• {platform} (`string`) Platform name (e.g. "codeforces").
|
||||||
|
• {contest_id} (`string`) Contest identifier (e.g. "1933").
|
||||||
filename Custom function to generate filenames
|
• {source_file} (`string`) Path to source file.
|
||||||
function(contest, problem_id, problem_letter)
|
• {input_file} (`string`) Path to input file (.cpin).
|
||||||
(default: nil, uses problem_id + letter + ".cc")
|
• {output_file} (`string`) Path to output file (.cpout).
|
||||||
|
• {expected_file} (`string`) Path to expected output file.
|
||||||
|
• {contest_config} (`table`) Contest configuration.
|
||||||
|
|
||||||
WORKFLOW *cp-workflow*
|
WORKFLOW *cp-workflow*
|
||||||
|
|
||||||
|
|
@ -272,19 +284,13 @@ maintains proper file associations.
|
||||||
|
|
||||||
SNIPPETS *cp-snippets*
|
SNIPPETS *cp-snippets*
|
||||||
|
|
||||||
cp.nvim integrates with LuaSnip for automatic template expansion. When you
|
cp.nvim integrates with LuaSnip for automatic template expansion. Built-in
|
||||||
open a new problem file, type the contest name and press <Tab> to expand.
|
snippets include basic C++ and Python templates for each contest type.
|
||||||
|
|
||||||
Built-in snippets include basic C++ and Python templates for each contest type.
|
Snippet trigger names must EXACTLY match platform names ("codeforces" for
|
||||||
Custom snippets can be added via configuration.
|
CodeForces, "cses" for CSES, etc.).
|
||||||
|
|
||||||
IMPORTANT: Snippet trigger names must exactly match the contest/platform names:
|
Custom snippets can be added via the `snippets` configuration field.
|
||||||
- "codeforces" for Codeforces problems
|
|
||||||
- "atcoder" for AtCoder problems
|
|
||||||
- "cses" for CSES problems
|
|
||||||
|
|
||||||
The plugin automatically selects the appropriate template based on the file
|
|
||||||
extension (e.g., .cc files get C++ templates, .py files get Python templates).
|
|
||||||
|
|
||||||
HEALTH CHECK *cp-health*
|
HEALTH CHECK *cp-health*
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
---@class Hooks
|
---@class Hooks
|
||||||
---@field before_run? fun(ctx: HookContext)
|
---@field before_run? fun(ctx: HookContext)
|
||||||
---@field before_debug? fun(ctx: HookContext)
|
---@field before_debug? fun(ctx: HookContext)
|
||||||
|
---@field setup_code? fun(ctx: HookContext)
|
||||||
|
|
||||||
---@class cp.Config
|
---@class cp.Config
|
||||||
---@field contests table<string, ContestConfig>
|
---@field contests table<string, ContestConfig>
|
||||||
|
|
@ -67,78 +68,18 @@ local filetype_to_language = {
|
||||||
|
|
||||||
---@type cp.Config
|
---@type cp.Config
|
||||||
M.defaults = {
|
M.defaults = {
|
||||||
contests = {
|
contests = {},
|
||||||
default = {
|
|
||||||
cpp = {
|
|
||||||
compile = {
|
|
||||||
"g++",
|
|
||||||
"-std=c++{version}",
|
|
||||||
"-O2",
|
|
||||||
"-DLOCAL",
|
|
||||||
"-Wall",
|
|
||||||
"-Wextra",
|
|
||||||
"{source}",
|
|
||||||
"-o",
|
|
||||||
"{binary}",
|
|
||||||
},
|
|
||||||
run = { "{binary}" },
|
|
||||||
debug = {
|
|
||||||
"g++",
|
|
||||||
"-std=c++{version}",
|
|
||||||
"-g3",
|
|
||||||
"-fsanitize=address,undefined",
|
|
||||||
"-DLOCAL",
|
|
||||||
"{source}",
|
|
||||||
"-o",
|
|
||||||
"{binary}",
|
|
||||||
},
|
|
||||||
executable = nil,
|
|
||||||
version = 20,
|
|
||||||
extension = "cc",
|
|
||||||
},
|
|
||||||
python = {
|
|
||||||
compile = nil,
|
|
||||||
run = { "{source}" },
|
|
||||||
debug = { "{source}" },
|
|
||||||
executable = "python3",
|
|
||||||
extension = "py",
|
|
||||||
},
|
|
||||||
default_language = "cpp",
|
|
||||||
timeout_ms = 2000,
|
|
||||||
},
|
|
||||||
---@type PartialContestConfig
|
|
||||||
atcoder = {
|
|
||||||
---@type PartialLanguageConfig
|
|
||||||
cpp = { version = 23 },
|
|
||||||
},
|
|
||||||
---@type PartialContestConfig
|
|
||||||
codeforces = {
|
|
||||||
---@type PartialLanguageConfig
|
|
||||||
cpp = { version = 23 },
|
|
||||||
},
|
|
||||||
---@type PartialContestConfig
|
|
||||||
cses = {
|
|
||||||
---@type PartialLanguageConfig
|
|
||||||
cpp = { version = 20 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
snippets = {},
|
snippets = {},
|
||||||
hooks = {
|
hooks = {
|
||||||
before_run = nil,
|
before_run = nil,
|
||||||
before_debug = nil,
|
before_debug = nil,
|
||||||
|
setup_code = nil,
|
||||||
},
|
},
|
||||||
debug = false,
|
debug = false,
|
||||||
tile = nil,
|
tile = nil,
|
||||||
filename = nil,
|
filename = nil,
|
||||||
}
|
}
|
||||||
|
|
||||||
---@param base_config table
|
|
||||||
---@param contest_config table
|
|
||||||
---@return table
|
|
||||||
local function extend_contest_config(base_config, contest_config)
|
|
||||||
local result = vim.tbl_deep_extend("force", base_config, contest_config)
|
|
||||||
return result
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param user_config cp.UserConfig|nil
|
---@param user_config cp.UserConfig|nil
|
||||||
---@return cp.Config
|
---@return cp.Config
|
||||||
|
|
@ -161,6 +102,7 @@ function M.setup(user_config)
|
||||||
vim.validate({
|
vim.validate({
|
||||||
before_run = { user_config.hooks.before_run, { "function", "nil" }, true },
|
before_run = { user_config.hooks.before_run, { "function", "nil" }, true },
|
||||||
before_debug = { user_config.hooks.before_debug, { "function", "nil" }, true },
|
before_debug = { user_config.hooks.before_debug, { "function", "nil" }, true },
|
||||||
|
setup_code = { user_config.hooks.setup_code, { "function", "nil" }, true },
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -185,14 +127,6 @@ function M.setup(user_config)
|
||||||
end
|
end
|
||||||
|
|
||||||
local config = vim.tbl_deep_extend("force", M.defaults, user_config or {})
|
local config = vim.tbl_deep_extend("force", M.defaults, user_config or {})
|
||||||
|
|
||||||
local default_contest = config.contests.default
|
|
||||||
for contest_name, contest_config in pairs(config.contests) do
|
|
||||||
if contest_name ~= "default" then
|
|
||||||
config.contests[contest_name] = extend_contest_config(default_contest, contest_config)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return config
|
return config
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -218,9 +152,18 @@ local function default_filename(contest, contest_id, problem_id, config, languag
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local contest_config = config.contests[contest] or config.contests.default
|
local contest_config = config.contests[contest]
|
||||||
local target_language = language or contest_config.default_language
|
local target_language = language or contest_config.default_language
|
||||||
local language_config = contest_config[target_language]
|
local language_config = contest_config[target_language]
|
||||||
|
|
||||||
|
if not language_config then
|
||||||
|
error(("No language config found for '%s' in contest '%s'"):format(target_language, contest))
|
||||||
|
end
|
||||||
|
|
||||||
|
if not language_config.extension then
|
||||||
|
error(("No extension configured for language '%s' in contest '%s'"):format(target_language, contest))
|
||||||
|
end
|
||||||
|
|
||||||
return full_problem_id .. "." .. language_config.extension
|
return full_problem_id .. "." .. language_config.extension
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,13 +135,10 @@ local function setup_problem(contest_id, problem_id, language)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
vim.api.nvim_set_option_value("winbar", "", { scope = "local" })
|
if config.hooks and config.hooks.setup_code then
|
||||||
vim.api.nvim_set_option_value("foldlevel", 0, { scope = "local" })
|
local ctx = problem.create_context(state.platform, state.contest_id, state.problem_id, config)
|
||||||
vim.api.nvim_set_option_value("foldmethod", "marker", { scope = "local" })
|
config.hooks.setup_code(ctx)
|
||||||
vim.api.nvim_set_option_value("foldmarker", "{{{,}}}", { scope = "local" })
|
end
|
||||||
vim.api.nvim_set_option_value("foldtext", "", { scope = "local" })
|
|
||||||
|
|
||||||
vim.diagnostic.enable(false)
|
|
||||||
|
|
||||||
local source_buf = vim.api.nvim_get_current_buf()
|
local source_buf = vim.api.nvim_get_current_buf()
|
||||||
local input_buf = vim.fn.bufnr(ctx.input_file, true)
|
local input_buf = vim.fn.bufnr(ctx.input_file, true)
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
---@field height integer
|
---@field height integer
|
||||||
|
|
||||||
local M = {}
|
local M = {}
|
||||||
|
local languages = require("cp.languages")
|
||||||
|
|
||||||
function M.clearcol()
|
function M.clearcol()
|
||||||
vim.api.nvim_set_option_value("number", false, { scope = "local" })
|
vim.api.nvim_set_option_value("number", false, { scope = "local" })
|
||||||
|
|
@ -78,7 +79,7 @@ function M.restore_layout(state, tile_fn)
|
||||||
local source_file
|
local source_file
|
||||||
if source_files ~= "" then
|
if source_files ~= "" then
|
||||||
local files = vim.split(source_files, "\n")
|
local files = vim.split(source_files, "\n")
|
||||||
local valid_extensions = { "cc", "cpp", "cxx", "c", "py", "py3" }
|
local valid_extensions = vim.tbl_keys(languages.filetype_to_language)
|
||||||
for _, file in ipairs(files) do
|
for _, file in ipairs(files) do
|
||||||
local ext = vim.fn.fnamemodify(file, ":e")
|
local ext = vim.fn.fnamemodify(file, ":e")
|
||||||
if vim.tbl_contains(valid_extensions, ext) then
|
if vim.tbl_contains(valid_extensions, ext) then
|
||||||
|
|
@ -87,11 +88,9 @@ function M.restore_layout(state, tile_fn)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
source_file = source_file or files[1]
|
source_file = source_file or files[1]
|
||||||
else
|
|
||||||
source_file = problem_id .. ".cc"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if vim.fn.filereadable(source_file) == 0 then
|
if not source_file or vim.fn.filereadable(source_file) == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ neovim plugin for competitive programming.
|
||||||
|
|
||||||
https://private-user-images.githubusercontent.com/62671086/489116291-391976d1-c2f4-49e6-a79d-13ff05e9be86.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTc3NDQ1ODEsIm5iZiI6MTc1Nzc0NDI4MSwicGF0aCI6Ii82MjY3MTA4Ni80ODkxMTYyOTEtMzkxOTc2ZDEtYzJmNC00OWU2LWE3OWQtMTNmZjA1ZTliZTg2Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA5MTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwOTEzVDA2MTgwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI0Zjc0YmQzNWIzNGZkM2VjZjM3NGM0YmZmM2I3MmJkZGQ0YTczYjIxMTFiODc3MjQyMzY3ODc2ZTUxZDRkMzkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.MBK5q_Zxr0gWuzfjwmSbB7P7dtWrATrT5cDOosdPRuQ
|
https://private-user-images.githubusercontent.com/62671086/489116291-391976d1-c2f4-49e6-a79d-13ff05e9be86.mp4?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3NTc3NDQ1ODEsIm5iZiI6MTc1Nzc0NDI4MSwicGF0aCI6Ii82MjY3MTA4Ni80ODkxMTYyOTEtMzkxOTc2ZDEtYzJmNC00OWU2LWE3OWQtMTNmZjA1ZTliZTg2Lm1wND9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTA5MTMlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwOTEzVDA2MTgwMVomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWI0Zjc0YmQzNWIzNGZkM2VjZjM3NGM0YmZmM2I3MmJkZGQ0YTczYjIxMTFiODc3MjQyMzY3ODc2ZTUxZDRkMzkmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.MBK5q_Zxr0gWuzfjwmSbB7P7dtWrATrT5cDOosdPRuQ
|
||||||
|
|
||||||
|
[video config](https://github.com/barrett-ruth/dots/blob/main/nvim/lua/plugins/cp.lua)
|
||||||
|
|
||||||
> Sample test data from [codeforces](https://codeforces.com) is scraped via [cloudscraper](https://github.com/VeNoMouS/cloudscraper). Use at your own risk.
|
> Sample test data from [codeforces](https://codeforces.com) is scraped via [cloudscraper](https://github.com/VeNoMouS/cloudscraper). Use at your own risk.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue