fix(log): improve logging
This commit is contained in:
parent
62af1965f8
commit
a925686a17
10 changed files with 144 additions and 225 deletions
|
|
@ -7,15 +7,20 @@ local logger = require('cp.log')
|
|||
local platforms = constants.PLATFORMS
|
||||
|
||||
function M.handle_cache_command(cmd)
|
||||
cmd.platform = cmd.platform:lower()
|
||||
if cmd.subcommand == 'clear' then
|
||||
cache.load()
|
||||
if cmd.platform then
|
||||
if vim.tbl_contains(platforms, cmd.platform) then
|
||||
cache.clear_platform(cmd.platform)
|
||||
logger.log(('cleared cache for %s'):format(cmd.platform), vim.log.levels.INFO, true)
|
||||
logger.log(
|
||||
('Cache cleared for platform %s'):format(cmd.platform),
|
||||
vim.log.levels.INFO,
|
||||
true
|
||||
)
|
||||
else
|
||||
logger.log(
|
||||
('unknown platform: %s. Available: %s'):format(
|
||||
("Unknown platform: '%s'. Available: %s"):format(
|
||||
cmd.platform,
|
||||
table.concat(platforms, ', ')
|
||||
),
|
||||
|
|
@ -24,7 +29,7 @@ function M.handle_cache_command(cmd)
|
|||
end
|
||||
else
|
||||
cache.clear_all()
|
||||
logger.log('cleared all cache', vim.log.levels.INFO, true)
|
||||
logger.log('Cache cleared', vim.log.levels.INFO, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ function M.handle_pick_action()
|
|||
|
||||
if not config.picker then
|
||||
logger.log(
|
||||
'No picker configured. Set picker = "telescope" or picker = "fzf-lua" in config',
|
||||
'No picker configured. Set picker = "{telescope,fzf-lua}" in your config.',
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
|
|
@ -20,14 +20,14 @@ function M.handle_pick_action()
|
|||
local ok = pcall(require, 'telescope')
|
||||
if not ok then
|
||||
logger.log(
|
||||
'Telescope not available. Install telescope.nvim or change picker config',
|
||||
'telescope.nvim is not available. Install telescope.nvim xor change your picker config.',
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
end
|
||||
local ok_cp, telescope_picker = pcall(require, 'cp.pickers.telescope')
|
||||
if not ok_cp then
|
||||
logger.log('Failed to load telescope integration', vim.log.levels.ERROR)
|
||||
logger.log('Failed to load telescope integration.', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -36,14 +36,14 @@ function M.handle_pick_action()
|
|||
local ok, _ = pcall(require, 'fzf-lua')
|
||||
if not ok then
|
||||
logger.log(
|
||||
'fzf-lua not available. Install fzf-lua or change picker config',
|
||||
'fzf-lua is not available. Install fzf-lua xor change your picker config',
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
end
|
||||
local ok_cp, fzf_picker = pcall(require, 'cp.pickers.fzf_lua')
|
||||
if not ok_cp then
|
||||
logger.log('Failed to load fzf-lua integration', vim.log.levels.ERROR)
|
||||
logger.log('Failed to load fzf-lua integration.', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ local logger = require('cp.log')
|
|||
local snippets = require('cp.snippets')
|
||||
|
||||
if not vim.fn.has('nvim-0.10.0') then
|
||||
logger.log('[cp.nvim]: requires nvim-0.10.0+', vim.log.levels.ERROR)
|
||||
logger.log('Requires nvim-0.10.0+', vim.log.levels.ERROR)
|
||||
return {}
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ local M = {}
|
|||
|
||||
local cache = require('cp.cache')
|
||||
local config = require('cp.config').get_config()
|
||||
local constants = require('cp.constants')
|
||||
local logger = require('cp.log')
|
||||
local scraper = require('cp.scraper')
|
||||
|
||||
|
|
@ -21,7 +22,6 @@ local scraper = require('cp.scraper')
|
|||
|
||||
---@return cp.PlatformItem[]
|
||||
function M.get_platforms()
|
||||
local constants = require('cp.constants')
|
||||
local result = {}
|
||||
|
||||
for _, platform in ipairs(constants.PLATFORMS) do
|
||||
|
|
@ -40,7 +40,11 @@ end
|
|||
---@param platform string Platform identifier (e.g. "codeforces", "atcoder")
|
||||
---@return cp.ContestItem[]
|
||||
function M.get_contests_for_platform(platform)
|
||||
logger.log(('Loading %s contests..'):format(platform), vim.log.levels.INFO, true)
|
||||
logger.log(
|
||||
('Loading %s contests...'):format(constants.PLATFORM_DISPLAY_NAMES[platform]),
|
||||
vim.log.levels.INFO,
|
||||
true
|
||||
)
|
||||
|
||||
cache.load()
|
||||
|
||||
|
|
@ -62,21 +66,11 @@ function M.get_contests_for_platform(platform)
|
|||
end
|
||||
|
||||
logger.log(
|
||||
('Loaded %d %s contests.'):format(#picker_contests, platform),
|
||||
('Loaded %s %s contests.'):format(#picker_contests, constants.PLATFORM_DISPLAY_NAMES[platform]),
|
||||
vim.log.levels.INFO,
|
||||
true
|
||||
)
|
||||
return picker_contests
|
||||
end
|
||||
|
||||
---@param platform string Platform identifier
|
||||
---@param contest_id string Contest identifier
|
||||
---@param problem_id string Problem identifier
|
||||
function M.setup_problem(platform, contest_id, problem_id)
|
||||
vim.schedule(function()
|
||||
local cp = require('cp')
|
||||
cp.handle_command({ fargs = { platform, contest_id, problem_id } })
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ local state = require('cp.state')
|
|||
function M.restore_from_current_file()
|
||||
local current_file = vim.fn.expand('%:p')
|
||||
if current_file == '' then
|
||||
logger.log('No file is currently open', vim.log.levels.ERROR)
|
||||
logger.log('No file is currently open.', vim.log.levels.ERROR)
|
||||
return false
|
||||
end
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ function M.restore_from_current_file()
|
|||
local file_state = cache.get_file_state(current_file)
|
||||
if not file_state then
|
||||
logger.log(
|
||||
'No cached state found for current file. Use :CP <platform> <contest> <problem> first.',
|
||||
'No cached state found for current file. Use :CP <platform> <contest> <problem> [...] first.',
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return false
|
||||
|
|
@ -25,7 +25,7 @@ function M.restore_from_current_file()
|
|||
('Restoring from cached state: %s %s %s'):format(
|
||||
file_state.platform,
|
||||
file_state.contest_id,
|
||||
file_state.problem_id or 'N/A'
|
||||
file_state.problem_id
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ end
|
|||
---@return {code: integer, stdout: string, stderr: string}
|
||||
function M.compile_generic(language_config, substitutions)
|
||||
if not language_config.compile then
|
||||
logger.log('no compilation step required')
|
||||
logger.log('No compilation step required for language - skipping.')
|
||||
return { code = 0, stderr = '' }
|
||||
end
|
||||
|
||||
|
|
@ -73,9 +73,9 @@ function M.compile_generic(language_config, substitutions)
|
|||
result.stderr = ansi.bytes_to_string(result.stderr or '')
|
||||
|
||||
if result.code == 0 then
|
||||
logger.log(('compilation successful (%.1fms)'):format(compile_time), vim.log.levels.INFO)
|
||||
logger.log(('Compilation successful in %.1fms.'):format(compile_time), vim.log.levels.INFO)
|
||||
else
|
||||
logger.log(('compilation failed (%.1fms)'):format(compile_time))
|
||||
logger.log(('Compilation failed in %.1fms.'):format(compile_time))
|
||||
end
|
||||
|
||||
return result
|
||||
|
|
@ -107,14 +107,14 @@ local function execute_command(cmd, input_data, timeout_ms)
|
|||
local actual_code = result.code or 0
|
||||
|
||||
if result.code == 124 then
|
||||
logger.log(('execution timed out after %.1fms'):format(execution_time), vim.log.levels.WARN)
|
||||
logger.log(('Execution timed out in %.1fms.'):format(execution_time), vim.log.levels.WARN)
|
||||
elseif actual_code ~= 0 then
|
||||
logger.log(
|
||||
('execution failed (exit code %d, %.1fms)'):format(actual_code, execution_time),
|
||||
('Execution failed in %.1fms (exit code %d).'):format(execution_time, actual_code),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
else
|
||||
logger.log(('execution successful (%.1fms)'):format(execution_time))
|
||||
logger.log(('Execution successful in %.1fms.'):format(execution_time))
|
||||
end
|
||||
|
||||
return {
|
||||
|
|
@ -177,8 +177,8 @@ function M.compile_problem(contest_config, is_debug)
|
|||
local state = require('cp.state')
|
||||
local source_file = state.get_source_file()
|
||||
if not source_file then
|
||||
logger.log('No source file found', vim.log.levels.ERROR)
|
||||
return { success = false, output = 'No source file found' }
|
||||
logger.log('No source file found.', vim.log.levels.ERROR)
|
||||
return { success = false, output = 'No source file found.' }
|
||||
end
|
||||
|
||||
local language = get_language_from_file(source_file, contest_config)
|
||||
|
|
@ -186,7 +186,7 @@ function M.compile_problem(contest_config, is_debug)
|
|||
|
||||
if not language_config then
|
||||
logger.log('No configuration for language: ' .. language, vim.log.levels.ERROR)
|
||||
return { success = false, output = 'No configuration for language: ' .. language }
|
||||
return { success = false, output = ('No configuration for language %s.'):format(language) }
|
||||
end
|
||||
|
||||
local binary_file = state.get_binary_file()
|
||||
|
|
@ -203,10 +203,6 @@ function M.compile_problem(contest_config, is_debug)
|
|||
if compile_result.code ~= 0 then
|
||||
return { success = false, output = compile_result.stdout or 'unknown error' }
|
||||
end
|
||||
logger.log(
|
||||
('compilation successful (%s)'):format(is_debug and 'debug mode' or 'test mode'),
|
||||
vim.log.levels.INFO
|
||||
)
|
||||
end
|
||||
|
||||
return { success = true, output = nil }
|
||||
|
|
@ -220,7 +216,10 @@ function M.run_problem(contest_config, is_debug)
|
|||
local output_file = state.get_output_file()
|
||||
|
||||
if not source_file or not output_file then
|
||||
logger.log('Missing required file paths', vim.log.levels.ERROR)
|
||||
logger.log(
|
||||
('Missing required file paths %s and %s'):format(source_file, output_file),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -257,13 +256,14 @@ function M.run_problem(contest_config, is_debug)
|
|||
|
||||
local cache = require('cp.cache')
|
||||
cache.load()
|
||||
|
||||
local platform = state.get_platform()
|
||||
local contest_id = state.get_contest_id()
|
||||
local problem_id = state.get_problem_id()
|
||||
local expected_file = state.get_expected_file()
|
||||
|
||||
if not platform or not contest_id or not expected_file then
|
||||
logger.log('configure a contest before running a problem', vim.log.levels.ERROR)
|
||||
logger.log('Configure a contest before running a problem', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
local timeout_ms, _ = cache.get_constraints(platform, contest_id, problem_id)
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ local function run_single_test_case(contest_config, cp_config, test_case)
|
|||
}
|
||||
|
||||
if language_config.compile and binary_file and vim.fn.filereadable(binary_file) == 0 then
|
||||
logger.log('binary not found, compiling first...')
|
||||
logger.log('Binary not found - compiling first.')
|
||||
local compile_cmd = substitute_template(language_config.compile, substitutions)
|
||||
local redirected_cmd = vim.deepcopy(compile_cmd)
|
||||
redirected_cmd[#redirected_cmd] = redirected_cmd[#redirected_cmd] .. ' 2>&1'
|
||||
|
|
@ -219,9 +219,6 @@ local function run_single_test_case(contest_config, cp_config, test_case)
|
|||
local start_time = vim.uv.hrtime()
|
||||
local timeout_ms = run_panel_state.constraints and run_panel_state.constraints.timeout_ms or 2000
|
||||
|
||||
if not run_panel_state.constraints then
|
||||
logger.log('no problem constraints available, using default 2000ms timeout')
|
||||
end
|
||||
local redirected_run_cmd = vim.deepcopy(run_cmd)
|
||||
redirected_run_cmd[#redirected_run_cmd] = redirected_run_cmd[#redirected_run_cmd] .. ' 2>&1'
|
||||
local result = vim
|
||||
|
|
@ -315,14 +312,7 @@ function M.load_test_cases(state)
|
|||
state.get_problem_id()
|
||||
)
|
||||
|
||||
local constraint_info = run_panel_state.constraints
|
||||
and string.format(
|
||||
' with %dms/%dMB limits',
|
||||
run_panel_state.constraints.timeout_ms,
|
||||
run_panel_state.constraints.memory_mb
|
||||
)
|
||||
or ''
|
||||
logger.log(('loaded %d test case(s)%s'):format(#test_cases, constraint_info), vim.log.levels.INFO)
|
||||
logger.log(('Loaded %d test case(s)'):format(#test_cases), vim.log.levels.INFO)
|
||||
return #test_cases > 0
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ local logger = require('cp.log')
|
|||
|
||||
local function syshandle(result)
|
||||
if result.code ~= 0 then
|
||||
local msg = 'Scraper failed: ' .. (result.error or result.stderr or 'Unknown error')
|
||||
local msg = 'Scraper failed: ' .. (result.stderr or 'Unknown error')
|
||||
logger.log(msg, vim.log.levels.ERROR)
|
||||
return {
|
||||
success = false,
|
||||
|
|
@ -69,13 +69,17 @@ end
|
|||
function M.scrape_contest_metadata(platform, contest_id, callback)
|
||||
run_scraper(platform, 'metadata', { contest_id }, {
|
||||
on_exit = function(result)
|
||||
if not result.success then
|
||||
if not result.success or vim.tbl_isempty(result.data.problems) then
|
||||
logger.log(
|
||||
('Failed to scrape metadata for %s contest %s - aborting.'):format(platform, contest_id)
|
||||
('Failed to scrape metadata for %s contest %s - aborting.'):format(platform, contest_id),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
end
|
||||
callback(result.data)
|
||||
|
||||
if type(callback) == 'function' then
|
||||
callback(result.data)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
|
@ -83,7 +87,10 @@ end
|
|||
function M.scrape_contest_list(platform)
|
||||
local result = run_scraper(platform, 'contests', {}, { sync = true })
|
||||
if not result.success or not result.data.contests then
|
||||
logger.log(('Could not scrape contests list for platform %s: %s'):format(platform, result.msg))
|
||||
logger.log(
|
||||
('Could not scrape contests list for platform %s: %s'):format(platform, result.msg),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return {}
|
||||
end
|
||||
|
||||
|
|
@ -123,7 +130,9 @@ function M.scrape_problem_tests(platform, contest_id, problem_id, callback)
|
|||
end
|
||||
end)
|
||||
|
||||
callback(result.data)
|
||||
if type(callback) == 'function' then
|
||||
callback(result.data)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
|
|
|||
254
lua/cp/setup.lua
254
lua/cp/setup.lua
|
|
@ -28,155 +28,7 @@ function M.set_platform(platform)
|
|||
return true
|
||||
end
|
||||
|
||||
-- NOTE: this is backwards
|
||||
function M.setup_contest(platform, contest_id, problem_id, language)
|
||||
if not state.get_platform() then
|
||||
logger.log('No platform configured. Use :CP <platform> <contest> [...] first.')
|
||||
return
|
||||
end
|
||||
|
||||
local config = config_module.get_config()
|
||||
|
||||
if not vim.tbl_contains(config.scrapers, platform) then
|
||||
logger.log(('Scraping disabled for %s - aborting'):format(platform), vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
state.set_contest_id(contest_id)
|
||||
logger.log('fetching contests problems...', vim.log.levels.INFO, true)
|
||||
|
||||
scraper.scrape_contest_metadata(platform, contest_id, function(result)
|
||||
local problems = result.problems
|
||||
if vim.tbl_isempty(problems) then
|
||||
logger.log('no problems found in contest', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
logger.log(('found %d problems'):format(#problems))
|
||||
|
||||
local target_problem = problem_id or problems[1].id
|
||||
|
||||
if problem_id then
|
||||
local problem_exists = false
|
||||
for _, prob in ipairs(problems) do
|
||||
if prob.id == problem_id then
|
||||
problem_exists = true
|
||||
break
|
||||
end
|
||||
end
|
||||
if not problem_exists then
|
||||
logger.log(
|
||||
('invalid problem %s for contest %s'):format(problem_id, contest_id),
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- NOTE: should setup buffer without a name, then save it with proper name later for immediate editing
|
||||
M.setup_problem(contest_id, target_problem, language)
|
||||
|
||||
M.scrape_remaining_problems(platform, contest_id, problems)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.setup_problem(contest_id, problem_id, language)
|
||||
if not state.get_platform() then
|
||||
logger.log('no platform set. run :CP <platform> <contest> first', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local config = config_module.get_config()
|
||||
local platform = state.get_platform() or ''
|
||||
|
||||
logger.log(('setting up problem %s%s...'):format(contest_id, problem_id or ''))
|
||||
|
||||
state.set_contest_id(contest_id)
|
||||
state.set_problem_id(problem_id)
|
||||
|
||||
vim.schedule(function()
|
||||
local ok, err = pcall(function()
|
||||
vim.cmd.only({ mods = { silent = true } })
|
||||
|
||||
local source_file = state.get_source_file(language)
|
||||
if not source_file then
|
||||
return
|
||||
end
|
||||
vim.cmd.e(source_file)
|
||||
local source_buf = vim.api.nvim_get_current_buf()
|
||||
|
||||
if vim.api.nvim_buf_get_lines(source_buf, 0, -1, true)[1] == '' then
|
||||
local has_luasnip, luasnip = pcall(require, 'luasnip')
|
||||
if has_luasnip then
|
||||
local filetype = vim.api.nvim_get_option_value('filetype', { buf = source_buf })
|
||||
local language_name = constants.filetype_to_language[filetype]
|
||||
local canonical_language = constants.canonical_filetypes[language_name] or language_name
|
||||
local prefixed_trigger = ('cp.nvim/%s.%s'):format(platform, canonical_language)
|
||||
|
||||
vim.api.nvim_buf_set_lines(0, 0, -1, false, { prefixed_trigger })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, #prefixed_trigger })
|
||||
vim.cmd.startinsert({ bang = true })
|
||||
|
||||
vim.schedule(function()
|
||||
if luasnip.expandable() then
|
||||
luasnip.expand()
|
||||
else
|
||||
vim.api.nvim_buf_set_lines(0, 0, 1, false, { '' })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
end
|
||||
vim.cmd.stopinsert()
|
||||
end)
|
||||
else
|
||||
vim.api.nvim_input(('i%s<c-space><esc>'):format(platform))
|
||||
end
|
||||
end
|
||||
|
||||
if config.hooks and config.hooks.setup_code then
|
||||
config.hooks.setup_code(state)
|
||||
end
|
||||
|
||||
cache.set_file_state(vim.fn.expand('%:p'), platform, contest_id, problem_id, language)
|
||||
|
||||
logger.log(('ready - problem %s'):format(state.get_base_name()))
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
logger.log(('setup error: %s'):format(err), vim.log.levels.ERROR)
|
||||
end
|
||||
end)
|
||||
|
||||
local cached_tests = cache.get_test_cases(platform, contest_id, problem_id)
|
||||
if cached_tests then
|
||||
state.set_test_cases(cached_tests)
|
||||
logger.log(('using cached test cases (%d)'):format(#cached_tests))
|
||||
else
|
||||
logger.log('loading test cases...')
|
||||
|
||||
scraper.scrape_problem_tests(platform, contest_id, problem_id, function(result)
|
||||
state.set_test_cases(result.tests or {})
|
||||
|
||||
cached_tests = {}
|
||||
for i, test_case in ipairs(result.tests or {}) do
|
||||
table.insert(cached_tests, {
|
||||
index = i,
|
||||
input = test_case.input,
|
||||
expected = test_case.expected,
|
||||
})
|
||||
end
|
||||
|
||||
cache.set_test_cases(
|
||||
platform,
|
||||
contest_id,
|
||||
problem_id,
|
||||
cached_tests,
|
||||
result.timeout_ms,
|
||||
result.memory_mb
|
||||
)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
function M.scrape_remaining_problems(platform, contest_id, problems)
|
||||
local function scrape_contest_problems(platform, contest_id, problems)
|
||||
cache.load()
|
||||
local missing_problems = {}
|
||||
|
||||
|
|
@ -188,21 +40,98 @@ function M.scrape_remaining_problems(platform, contest_id, problems)
|
|||
end
|
||||
|
||||
if vim.tbl_isempty(missing_problems) then
|
||||
logger.log('all problems already cached')
|
||||
logger.log(('All problems already cached for %s contest %s'):format(platform, contest_id))
|
||||
return
|
||||
end
|
||||
|
||||
logger.log(('caching %d remaining problems...'):format(#missing_problems))
|
||||
|
||||
for _, prob in ipairs(missing_problems) do
|
||||
scraper.scrape_problem_tests(platform, contest_id, prob.id, function(result)
|
||||
if result.success then
|
||||
logger.log(('background: scraped problem %s'):format(prob.id))
|
||||
end
|
||||
end)
|
||||
scraper.scrape_problem_tests(platform, contest_id, prob.id)
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup_contest(platform, contest_id, problem_id, language)
|
||||
if not state.get_platform() then
|
||||
logger.log('No platform configured. Use :CP <platform> <contest> [...] first.')
|
||||
return
|
||||
end
|
||||
|
||||
local config = config_module.get_config()
|
||||
|
||||
if not vim.tbl_contains(config.scrapers, platform) then
|
||||
logger.log(('Scraping disabled for %s - aborting.'):format(platform), vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
state.set_contest_id(contest_id)
|
||||
logger.log('Fetching contests problems...', vim.log.levels.INFO, true)
|
||||
|
||||
scraper.scrape_contest_metadata(platform, contest_id, function(result)
|
||||
local problems = result.problems
|
||||
|
||||
logger.log(('found %d problems'):format(#problems))
|
||||
|
||||
local target_problem = problem_id or problems[1].id
|
||||
|
||||
M.setup_problem(contest_id, target_problem, language)
|
||||
|
||||
scrape_contest_problems(platform, contest_id, problems)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.setup_problem(contest_id, problem_id, language)
|
||||
if not state.get_platform() then
|
||||
logger.log('No platform set. run :CP <platform> <contest> first', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local config = config_module.get_config()
|
||||
local platform = state.get_platform() or ''
|
||||
|
||||
state.set_contest_id(contest_id)
|
||||
state.set_problem_id(problem_id)
|
||||
|
||||
vim.schedule(function()
|
||||
vim.cmd.only({ mods = { silent = true } })
|
||||
|
||||
local source_file = state.get_source_file(language)
|
||||
if not source_file then
|
||||
return
|
||||
end
|
||||
vim.cmd.e(source_file)
|
||||
local source_buf = vim.api.nvim_get_current_buf()
|
||||
|
||||
if vim.api.nvim_buf_get_lines(source_buf, 0, -1, true)[1] == '' then
|
||||
local has_luasnip, luasnip = pcall(require, 'luasnip')
|
||||
if has_luasnip then
|
||||
local filetype = vim.api.nvim_get_option_value('filetype', { buf = source_buf })
|
||||
local language_name = constants.filetype_to_language[filetype]
|
||||
local canonical_language = constants.canonical_filetypes[language_name] or language_name
|
||||
local prefixed_trigger = ('cp.nvim/%s.%s'):format(platform, canonical_language)
|
||||
|
||||
vim.api.nvim_buf_set_lines(0, 0, -1, false, { prefixed_trigger })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, #prefixed_trigger })
|
||||
vim.cmd.startinsert({ bang = true })
|
||||
|
||||
vim.schedule(function()
|
||||
if luasnip.expandable() then
|
||||
luasnip.expand()
|
||||
else
|
||||
vim.api.nvim_buf_set_lines(0, 0, 1, false, { '' })
|
||||
vim.api.nvim_win_set_cursor(0, { 1, 0 })
|
||||
end
|
||||
vim.cmd.stopinsert()
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
if config.hooks and config.hooks.setup_code then
|
||||
config.hooks.setup_code(state)
|
||||
end
|
||||
|
||||
cache.set_file_state(vim.fn.expand('%:p'), platform, contest_id, problem_id, language)
|
||||
end)
|
||||
end
|
||||
|
||||
function M.navigate_problem(direction, language)
|
||||
local platform = state.get_platform()
|
||||
local contest_id = state.get_contest_id()
|
||||
|
|
@ -219,7 +148,7 @@ function M.navigate_problem(direction, language)
|
|||
cache.load()
|
||||
local contest_data = cache.get_contest_data(platform, contest_id)
|
||||
if not contest_data or not contest_data.problems then
|
||||
logger.log('no contest data available', vim.log.levels.ERROR)
|
||||
logger.log('No contest data available', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
|
|
@ -232,19 +161,12 @@ function M.navigate_problem(direction, language)
|
|||
end
|
||||
end
|
||||
|
||||
if not current_index then
|
||||
logger.log('current problem not found in contest', vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
local new_index = current_index + direction
|
||||
if new_index < 1 or new_index > #problems then
|
||||
logger.log('no more problems in that direction', vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
|
||||
local new_problem = problems[new_index]
|
||||
M.setup_problem(contest_id, new_problem.id, language)
|
||||
M.setup_problem(contest_id, problems[new_index].id, language)
|
||||
end
|
||||
|
||||
return M
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue