Merge branch 'main' into feat/template-file-support

This commit is contained in:
Barrett Ruth 2026-02-26 22:56:50 -05:00 committed by GitHub
commit 5b56ff7980
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 159 additions and 30 deletions

View file

@ -1,8 +1,16 @@
{ {
"runtime.version": "LuaJIT", "runtime": {
"runtime.path": ["lua/?.lua", "lua/?/init.lua"], "version": "LuaJIT",
"diagnostics.globals": ["vim"], "path": ["lua/?.lua", "lua/?/init.lua"]
"workspace.library": ["$VIMRUNTIME/lua", "${3rd}/luv/library"], },
"workspace.checkThirdParty": false, "diagnostics": {
"completion.callSnippet": "Replace" "globals": ["vim"]
},
"workspace": {
"library": ["$VIMRUNTIME/lua", "${3rd}/luv/library", "${3rd}/busted/library"],
"checkThirdParty": false
},
"completion": {
"callSnippet": "Replace"
}
} }

View file

@ -888,6 +888,116 @@ Functions ~
Parameters: ~ Parameters: ~
{bufnr} (integer) Buffer handle {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?) Non-nil when the test panel is open.
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* PANEL KEYMAPS *cp-panel-keys*

View file

@ -346,6 +346,8 @@ function M.get_data_pretty()
return vim.inspect(cache_data) return vim.inspect(cache_data)
end end
M._cache = cache_data function M.get_raw_cache()
return cache_data
end
return M return M

View file

@ -13,7 +13,7 @@ local function check()
vim.health.error('cp.nvim requires Neovim 0.10.0+') vim.health.error('cp.nvim requires Neovim 0.10.0+')
end end
local uname = vim.loop.os_uname() local uname = vim.uv.os_uname()
if uname.sysname == 'Windows_NT' then if uname.sysname == 'Windows_NT' then
vim.health.error('Windows is not supported') vim.health.error('Windows is not supported')
end end

View file

@ -276,26 +276,35 @@ function M.run_all_test_cases(indices, debug, on_each, on_done)
end end
end end
local function run_next(pos) if #to_run == 0 then
if pos > #to_run then logger.log(
logger.log( ('Finished %s %d test cases.'):format(debug and 'debugging' or 'running', 0),
('Finished %s %d test cases.'):format(debug and 'debugging' or 'running', #to_run), vim.log.levels.INFO,
vim.log.levels.INFO, true
true )
) on_done(panel_state.test_cases)
on_done(panel_state.test_cases) return
return
end
M.run_test_case(to_run[pos], debug, function()
if on_each then
on_each(pos, #to_run)
end
run_next(pos + 1)
end)
end end
run_next(1) local total = #to_run
local remaining = total
for _, idx in ipairs(to_run) do
M.run_test_case(idx, debug, function()
if on_each then
on_each(idx, total)
end
remaining = remaining - 1
if remaining == 0 then
logger.log(
('Finished %s %d test cases.'):format(debug and 'debugging' or 'running', total),
vim.log.levels.INFO,
true
)
on_done(panel_state.test_cases)
end
end)
end
end end
---@return PanelState ---@return PanelState

View file

@ -57,7 +57,7 @@ local function run_scraper(platform, subcommand, args, opts)
env.CONDA_PREFIX = '' env.CONDA_PREFIX = ''
if opts and opts.ndjson then if opts and opts.ndjson then
local uv = vim.loop local uv = vim.uv
local stdout = uv.new_pipe(false) local stdout = uv.new_pipe(false)
local stderr = uv.new_pipe(false) local stderr = uv.new_pipe(false)
local buf = '' local buf = ''

View file

@ -198,7 +198,7 @@ function M.setup_contest(platform, contest_id, problem_id, language)
contest_id = contest_id, contest_id = contest_id,
language = lang, language = lang,
requested_problem_id = problem_id, requested_problem_id = problem_id,
token = vim.loop.hrtime(), token = vim.uv.hrtime(),
}) })
logger.log('Fetching contests problems...', vim.log.levels.INFO, true) logger.log('Fetching contests problems...', vim.log.levels.INFO, true)

View file

@ -5,7 +5,7 @@ local logger = require('cp.log')
local _nix_python = nil local _nix_python = nil
local _nix_discovered = false local _nix_discovered = false
local uname = vim.loop.os_uname() local uname = vim.uv.os_uname()
local _time_cached = false local _time_cached = false
local _time_path = nil local _time_path = nil
@ -336,7 +336,7 @@ function M.timeout_capability()
end end
function M.cwd_executables() function M.cwd_executables()
local uv = vim.uv or vim.loop local uv = vim.uv
local req = uv.fs_scandir('.') local req = uv.fs_scandir('.')
if not req then if not req then
return {} return {}