diff --git a/doc/cp.txt b/doc/cp.txt index 7570cc1..7b848ab 100644 --- a/doc/cp.txt +++ b/doc/cp.txt @@ -9,12 +9,13 @@ cp.nvim is a competitive programming plugin that automates problem setup, compilation, and testing workflow for online judges. Supported platforms: AtCoder, Codeforces, CSES +Supported languages: C++, Python REQUIREMENTS *cp-requirements* - Neovim 0.10.0+ - uv package manager (https://docs.astral.sh/uv/) -- C++ compiler (g++/clang++) +- Language runtime/compiler (g++, python3) Optional: - LuaSnip for template expansion (https://github.com/L3MON4D3/LuaSnip) @@ -51,8 +52,8 @@ Action Commands ~ :CP debug Compile with debug flags and run current problem. Includes sanitizers and debug symbols. -:CP diff Enter diff mode to compare actual vs expected - output. Run again to exit diff mode. +:CP test Open enhanced test viewer showing individual + test case results with pass/fail status. Navigation Commands ~ diff --git a/lua/cp/execute.lua b/lua/cp/execute.lua index 2182939..87daa60 100644 --- a/lua/cp/execute.lua +++ b/lua/cp/execute.lua @@ -7,10 +7,6 @@ local filetype_to_language = { c = "cpp", py = "python", py3 = "python", - rs = "rust", - java = "java", - js = "javascript", - go = "go", } local function get_language_from_file(source_file) @@ -138,20 +134,36 @@ end function M.run_problem(ctx, contest_config, is_debug) ensure_directories() - local flags = is_debug and contest_config.debug_flags or contest_config.compile_flags + local language = get_language_from_file(ctx.source_file) + local language_config = contest_config[language] - local compile_result = compile_cpp(ctx.source_file, ctx.binary_file, flags) - if compile_result.code ~= 0 then - vim.fn.writefile({ compile_result.stderr }, ctx.output_file) + if not language_config then + vim.fn.writefile({ "Error: No configuration for language: " .. language }, ctx.output_file) return end + local substitutions = { + source = ctx.source_file, + binary = ctx.binary_file, + version = tostring(language_config.version or ""), + } + + local compile_cmd = is_debug and language_config.debug or language_config.compile + if compile_cmd then + local compile_result = compile_generic(language_config, substitutions) + if compile_result.code ~= 0 then + vim.fn.writefile({ compile_result.stderr }, ctx.output_file) + return + end + end + local input_data = "" if vim.fn.filereadable(ctx.input_file) == 1 then input_data = table.concat(vim.fn.readfile(ctx.input_file), "\n") .. "\n" end - local exec_result = execute_binary(ctx.binary_file, input_data, contest_config.timeout_ms) + local run_cmd = build_command(language_config.run, language_config.executable, substitutions) + local exec_result = execute_command(run_cmd, input_data, contest_config.timeout_ms) local formatted_output = format_output(exec_result, ctx.expected_file, is_debug) local output_buf = vim.fn.bufnr(ctx.output_file) @@ -172,18 +184,38 @@ function M.run_individual_tests(ctx, test_cases, contest_config, is_debug) return {} end - local flags = is_debug and contest_config.debug_flags or contest_config.compile_flags - local compile_result = compile_cpp(ctx.source_file, ctx.binary_file, flags) - if compile_result.code ~= 0 then + local language = get_language_from_file(ctx.source_file) + local language_config = contest_config[language] + + if not language_config then return { - compile_error = compile_result.stderr, + compile_error = "Error: No configuration for language: " .. language, results = {}, } end + local substitutions = { + source = ctx.source_file, + binary = ctx.binary_file, + version = tostring(language_config.version or ""), + } + + local compile_cmd = is_debug and language_config.debug or language_config.compile + if compile_cmd then + local compile_result = compile_generic(language_config, substitutions) + if compile_result.code ~= 0 then + return { + compile_error = compile_result.stderr, + results = {}, + } + end + end + + local run_cmd = build_command(language_config.run, language_config.executable, substitutions) + local results = {} for i, test_case in ipairs(test_cases) do - local exec_result = execute_binary(ctx.binary_file, test_case.input, contest_config.timeout_ms) + local exec_result = execute_command(run_cmd, test_case.input, contest_config.timeout_ms) local actual_lines = vim.split(exec_result.stdout, "\n") while #actual_lines > 0 and actual_lines[#actual_lines] == "" do diff --git a/readme.md b/readme.md index 5adcaec..6b6bf83 100644 --- a/readme.md +++ b/readme.md @@ -9,9 +9,10 @@ https://private-user-images.githubusercontent.com/62671086/489116291-391976d1-c2 ## Features - Support for multiple online judges ([AtCoder](https://atcoder.jp/), [Codeforces](https://codeforces.com/), [CSES](https://cses.fi)) +- Multi-language support (C++, Python) - Automatic problem scraping and test case management - Integrated build, run, and debug commands -- Diff mode for comparing output with expected results +- Enhanced test viewer with individual test case management - LuaSnip integration for contest-specific snippets ## Requirements