cleanup window layout

This commit is contained in:
Barrett Ruth 2025-09-12 17:19:20 -05:00
parent 3f49721657
commit 0db6fa96b4
9 changed files with 118 additions and 76 deletions

View file

@ -1,13 +0,0 @@
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*/io/*.in",
callback = function()
vim.bo.filetype = "cpinput"
end,
})
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*/io/*.out",
callback = function()
vim.bo.filetype = "cpoutput"
end,
})

View file

@ -1,6 +0,0 @@
vim.opt_local.number = false
vim.opt_local.relativenumber = false
vim.opt_local.statuscolumn = ""
vim.opt_local.signcolumn = "no"
vim.opt_local.wrap = true
vim.opt_local.linebreak = true

View file

@ -14,4 +14,4 @@ highlight default link cpOutputDebug Comment
highlight default link cpOutputMatchesTrue DiffAdd
highlight default link cpOutputMatchesFalse DiffDelete
let b:current_syntax = "cpoutput"
let b:current_syntax = "cp"

View file

@ -21,30 +21,6 @@ local function get_plugin_path()
return vim.fn.fnamemodify(plugin_path, ":h:h:h")
end
local function setup_python_env()
local plugin_path = get_plugin_path()
local venv_dir = plugin_path .. "/.venv"
if vim.fn.executable("uv") == 0 then
log(
"uv is not installed. Install it to enable problem scraping: https://docs.astral.sh/uv/",
vim.log.levels.WARN
)
return false
end
if vim.fn.isdirectory(venv_dir) == 0 then
log("setting up Python environment for scrapers...")
local result = vim.system({ "uv", "sync" }, { cwd = plugin_path, text = true }):wait()
if result.code ~= 0 then
log("failed to setup Python environment: " .. result.stderr, vim.log.levels.ERROR)
return false
end
log("python environment setup complete")
end
return true
end
local competition_types = { "atcoder", "codeforces", "cses" }
@ -82,7 +58,7 @@ local function setup_problem(problem_id, problem_letter)
vim.g.cp_diff_mode = false
end
vim.cmd.only()
vim.cmd('silent only')
local scrape_result = scrape.scrape_problem(vim.g.cp_contest, problem_id, problem_letter)
@ -136,10 +112,12 @@ local function setup_problem(problem_id, problem_letter)
vim.cmd.vsplit(output)
vim.cmd.w()
vim.bo.filetype = "cp"
window.clearcol()
vim.cmd(("vertical resize %d"):format(math.floor(vim.o.columns * 0.3)))
vim.cmd.split(input)
vim.cmd.w()
vim.bo.filetype = "cp"
window.clearcol()
vim.cmd.wincmd("h")
@ -251,8 +229,6 @@ function M.setup(user_config)
end
initialized = true
setup_python_env()
vim.api.nvim_create_user_command("CP", function(opts)
local args = opts.fargs
if #args == 0 then

View file

@ -9,9 +9,45 @@ local function ensure_io_directory()
vim.fn.mkdir("io", "p")
end
local function log(msg, level)
vim.notify(("[cp.nvim]: %s"):format(msg), level or vim.log.levels.INFO)
end
local function setup_python_env()
local plugin_path = get_plugin_path()
local venv_dir = plugin_path .. "/.venv"
if vim.fn.executable("uv") == 0 then
log(
"uv is not installed. Install it to enable problem scraping: https://docs.astral.sh/uv/",
vim.log.levels.WARN
)
return false
end
if vim.fn.isdirectory(venv_dir) == 0 then
log("setting up Python environment for scrapers...")
local result = vim.system({ "uv", "sync" }, { cwd = plugin_path, text = true }):wait()
if result.code ~= 0 then
log("failed to setup Python environment: " .. result.stderr, vim.log.levels.ERROR)
return false
end
log("python environment setup complete")
end
return true
end
function M.scrape_problem(contest, problem_id, problem_letter)
ensure_io_directory()
if not setup_python_env() then
return {
success = false,
error = "Python environment setup failed",
}
end
local plugin_path = get_plugin_path()
local scraper_path = plugin_path .. "/scrapers/" .. contest .. ".py"
@ -47,14 +83,29 @@ function M.scrape_problem(contest, problem_id, problem_letter)
return data
end
local full_problem_id = data.problem_id
local full_problem_id = data.problem_id:lower()
local input_file = "io/" .. full_problem_id .. ".in"
local expected_file = "io/" .. full_problem_id .. ".expected"
if #data.test_cases > 0 then
local first_test = data.test_cases[1]
vim.fn.writefile(vim.split(first_test.input, "\n"), input_file)
vim.fn.writefile(vim.split(first_test.output, "\n"), expected_file)
local all_inputs = {}
local all_outputs = {}
for i, test_case in ipairs(data.test_cases) do
local input_lines = vim.split(test_case.input:gsub("\r", ""):gsub("\n+$", ""), "\n")
local output_lines = vim.split(test_case.output:gsub("\r", ""):gsub("\n+$", ""), "\n")
for _, line in ipairs(input_lines) do
table.insert(all_inputs, line)
end
for _, line in ipairs(output_lines) do
table.insert(all_outputs, line)
end
end
vim.fn.writefile(all_inputs, input_file)
vim.fn.writefile(all_outputs, expected_file)
end
return {

View file

@ -35,41 +35,77 @@ function M.restore_layout(state)
end
vim.cmd.diffoff()
vim.cmd(state.layout)
for win, win_state in pairs(state.windows) do
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
if vim.api.nvim_get_current_buf() == win_state.bufnr then
vim.fn.winrestview(win_state.view)
local problem_id = vim.fn.expand("%:t:r")
if problem_id == "" then
for win, win_state in pairs(state.windows) do
if vim.api.nvim_win_is_valid(win) and vim.api.nvim_buf_is_valid(win_state.bufnr) then
local bufname = vim.api.nvim_buf_get_name(win_state.bufnr)
if bufname:match("%.cc$") then
problem_id = vim.fn.fnamemodify(bufname, ":t:r")
break
end
end
end
end
if vim.api.nvim_win_is_valid(state.current_win) then
vim.api.nvim_set_current_win(state.current_win)
if problem_id ~= "" then
vim.cmd('silent only')
local base_fp = vim.fn.getcwd()
local input = ("%s/io/%s.in"):format(base_fp, problem_id)
local output = ("%s/io/%s.out"):format(base_fp, problem_id)
local source = problem_id .. ".cc"
vim.cmd.edit(source)
vim.cmd.vsplit(output)
vim.bo.filetype = "cp"
M.clearcol()
vim.cmd(("vertical resize %d"):format(math.floor(vim.o.columns * 0.3)))
vim.cmd.split(input)
vim.bo.filetype = "cp"
M.clearcol()
vim.cmd.wincmd("h")
else
vim.cmd(state.layout)
for win, win_state in pairs(state.windows) do
if vim.api.nvim_win_is_valid(win) then
vim.api.nvim_set_current_win(win)
if vim.api.nvim_get_current_buf() == win_state.bufnr then
vim.fn.winrestview(win_state.view)
end
end
end
if vim.api.nvim_win_is_valid(state.current_win) then
vim.api.nvim_set_current_win(state.current_win)
end
end
end
function M.setup_diff_layout(actual_output, expected_output, input_file)
vim.cmd.diffoff()
vim.cmd.only()
vim.cmd('silent only')
local output_lines = vim.split(actual_output, "\n")
local output_buf = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(output_buf, 0, -1, false, output_lines)
vim.bo[output_buf].filetype = "cpoutput"
vim.bo[output_buf].filetype = "cp"
vim.cmd.edit()
vim.api.nvim_set_current_buf(output_buf)
vim.cmd.diffthis()
M.clearcol()
vim.cmd.diffthis()
vim.cmd.vsplit(expected_output)
vim.cmd.diffthis()
vim.bo.filetype = "cp"
M.clearcol()
vim.cmd.diffthis()
vim.cmd.wincmd("h")
vim.cmd(("botright split %s"):format(input_file))
vim.bo.filetype = "cp"
M.clearcol()
vim.cmd.wincmd("k")
end

View file

@ -68,7 +68,7 @@ def main():
contest_id = sys.argv[1]
problem_letter = sys.argv[2]
problem_id = contest_id + problem_letter
problem_id = contest_id + problem_letter.lower()
url = parse_problem_url(contest_id, problem_letter)
print(f"Scraping: {url}", file=sys.stderr)
@ -88,6 +88,11 @@ def main():
test_cases = []
for input_data, output_data in tests:
test_cases.append({"input": input_data, "output": output_data})
if test_cases:
combined_input = str(len(test_cases)) + "\n" + "\n".join(tc["input"] for tc in test_cases)
combined_output = "\n".join(tc["output"] for tc in test_cases)
test_cases = [{"input": combined_input, "output": combined_output}]
result = {
"success": True,

View file

@ -43,16 +43,9 @@ def scrape(url: str):
output_lines.append(line_div.get_text().strip())
if input_lines and output_lines:
if len(input_lines) > 1 and input_lines[0].isdigit():
test_count = int(input_lines[0])
remaining_input = input_lines[1:]
for i in range(min(test_count, len(output_lines))):
if i < len(remaining_input):
tests.append((remaining_input[i], output_lines[i]))
else:
input_text = "\n".join(input_lines)
output_text = "\n".join(output_lines)
tests.append((input_text, output_text))
input_text = "\n".join(input_lines)
output_text = "\n".join(output_lines)
tests.append((input_text, output_text))
return tests
@ -84,7 +77,7 @@ def main():
contest_id = sys.argv[1]
problem_letter = sys.argv[2]
problem_id = contest_id + problem_letter.upper()
problem_id = contest_id + problem_letter.lower()
url = parse_problem_url(contest_id, problem_letter)
tests = scrape_sample_tests(url)