From 514761733bef7ed1207bac73bed40db8dafbdd2f Mon Sep 17 00:00:00 2001 From: Barrett Ruth Date: Fri, 19 Sep 2025 20:55:06 -0400 Subject: [PATCH] fix(scraper): relative python module import path --- lua/cp/highlight.lua | 22 ++-------- lua/cp/test_render.lua | 91 ++++++++++++++++++++++++++---------------- scrapers/codeforces.py | 2 +- scrapers/cses.py | 2 +- 4 files changed, 62 insertions(+), 55 deletions(-) diff --git a/lua/cp/highlight.lua b/lua/cp/highlight.lua index 8cf8bf4..02bf1ae 100644 --- a/lua/cp/highlight.lua +++ b/lua/cp/highlight.lua @@ -10,7 +10,6 @@ local M = {} ----Parse git diff markers and extract highlight information ---@param text string Raw git diff output line ---@return string cleaned_text, DiffHighlight[] local function parse_diff_line(text) @@ -52,7 +51,6 @@ local function parse_diff_line(text) return result_text, highlights end ----Parse complete git diff output ---@param diff_output string ---@return ParsedDiff function M.parse_git_diff(diff_output) @@ -64,10 +62,8 @@ function M.parse_git_diff(diff_output) local content_lines = {} local all_highlights = {} - -- Skip git diff header lines local content_started = false for _, line in ipairs(lines) do - -- Skip header lines (@@, +++, ---, index, etc.) if content_started or ( @@ -80,33 +76,27 @@ function M.parse_git_diff(diff_output) then content_started = true - -- Process content lines if line:match('^%+') then - -- Added line - remove + prefix and parse highlights - local clean_line = line:sub(2) -- Remove + prefix + local clean_line = line:sub(2) local parsed_line, line_highlights = parse_diff_line(clean_line) table.insert(content_lines, parsed_line) - -- Set line numbers for highlights local line_num = #content_lines for _, highlight in ipairs(line_highlights) do - highlight.line = line_num - 1 -- 0-based for extmarks + highlight.line = line_num - 1 table.insert(all_highlights, highlight) end - elseif not line:match('^%-') and not line:match('^\\') then -- Skip removed lines and "\ No newline" messages - -- Word-diff content line or unchanged line + elseif not line:match('^%-') and not line:match('^\\') then local clean_line = line:match('^%s') and line:sub(2) or line local parsed_line, line_highlights = parse_diff_line(clean_line) - -- Only add non-empty lines if parsed_line ~= '' then table.insert(content_lines, parsed_line) - -- Set line numbers for highlights local line_num = #content_lines for _, highlight in ipairs(line_highlights) do - highlight.line = line_num - 1 -- 0-based for extmarks + highlight.line = line_num - 1 table.insert(all_highlights, highlight) end end @@ -120,12 +110,10 @@ function M.parse_git_diff(diff_output) } end ----Apply highlights to a buffer using extmarks ---@param bufnr number ---@param highlights DiffHighlight[] ---@param namespace number function M.apply_highlights(bufnr, highlights, namespace) - -- Clear existing highlights in this namespace vim.api.nvim_buf_clear_namespace(bufnr, namespace, 0, -1) for _, highlight in ipairs(highlights) do @@ -139,13 +127,11 @@ function M.apply_highlights(bufnr, highlights, namespace) end end ----Create namespace for diff highlights ---@return number function M.create_namespace() return vim.api.nvim_create_namespace('cp_diff_highlights') end ----Parse and apply git diff to buffer ---@param bufnr number ---@param diff_output string ---@param namespace number diff --git a/lua/cp/test_render.lua b/lua/cp/test_render.lua index 749e89e..5227b28 100644 --- a/lua/cp/test_render.lua +++ b/lua/cp/test_render.lua @@ -53,37 +53,40 @@ local function format_exit_code(code) return signal_name and string.format('%d (%s)', code, signal_name) or tostring(code) end --- Compute column widths + aggregates local function compute_cols(test_state) - local w = { num = 3, status = 8, time = 6, exit = 11, limits = 12 } + local w = { num = 3, status = 8, time = 6, exit = 11, timeout = 8, memory = 8 } - local limits_str = '' + local timeout_str = '' + local memory_str = '' if test_state.constraints then - limits_str = - string.format('%d/%.0f', test_state.constraints.timeout_ms, test_state.constraints.memory_mb) + timeout_str = tostring(test_state.constraints.timeout_ms) + memory_str = string.format('%.0f', test_state.constraints.memory_mb) else - limits_str = '—' + timeout_str = '—' + memory_str = '—' end for i, tc in ipairs(test_state.test_cases) do local prefix = (i == test_state.current_index) and '>' or ' ' - w.num = math.max(w.num, #(prefix .. i)) - w.status = math.max(w.status, #(' ' .. M.get_status_info(tc).text)) + w.num = math.max(w.num, #(' ' .. prefix .. i .. ' ')) + w.status = math.max(w.status, #(' ' .. M.get_status_info(tc).text .. ' ')) local time_str = tc.time_ms and string.format('%.2f', tc.time_ms) or '—' - w.time = math.max(w.time, #time_str) - w.exit = math.max(w.exit, #(' ' .. format_exit_code(tc.code))) - w.limits = math.max(w.limits, #limits_str) + w.time = math.max(w.time, #(' ' .. time_str .. ' ')) + w.exit = math.max(w.exit, #(' ' .. format_exit_code(tc.code) .. ' ')) + w.timeout = math.max(w.timeout, #(' ' .. timeout_str .. ' ')) + w.memory = math.max(w.memory, #(' ' .. memory_str .. ' ')) end - w.num = math.max(w.num, #' #') - w.status = math.max(w.status, #' Status') - w.time = math.max(w.time, #' Runtime (ms)') - w.exit = math.max(w.exit, #' Exit Code') - w.limits = math.max(w.limits, #' Time (ms)/Mem (MB)') + w.num = math.max(w.num, #' # ') + w.status = math.max(w.status, #' Status ') + w.time = math.max(w.time, #' Runtime (ms) ') + w.exit = math.max(w.exit, #' Exit Code ') + w.timeout = math.max(w.timeout, #' Time (ms) ') + w.memory = math.max(w.memory, #' Mem (MB) ') - local sum = w.num + w.status + w.time + w.exit + w.limits - local inner = sum + 4 -- four inner vertical dividers - local total = inner + 2 -- two outer borders + local sum = w.num + w.status + w.time + w.exit + w.timeout + w.memory + local inner = sum + 5 + local total = inner + 2 return { w = w, sum = sum, inner = inner, total = total } end @@ -97,11 +100,12 @@ local function center(text, width) end local function right_align(text, width) - local pad = width - #text + local content = (' %s '):format(text) + local pad = width - #content if pad <= 0 then - return text + return content end - return string.rep(' ', pad) .. text + return string.rep(' ', pad) .. content end local function top_border(c) @@ -115,7 +119,9 @@ local function top_border(c) .. '┬' .. string.rep('─', w.exit) .. '┬' - .. string.rep('─', w.limits) + .. string.rep('─', w.timeout) + .. '┬' + .. string.rep('─', w.memory) .. '┐' end @@ -130,7 +136,9 @@ local function row_sep(c) .. '┼' .. string.rep('─', w.exit) .. '┼' - .. string.rep('─', w.limits) + .. string.rep('─', w.timeout) + .. '┼' + .. string.rep('─', w.memory) .. '┤' end @@ -145,7 +153,9 @@ local function bottom_border(c) .. '┴' .. string.rep('─', w.exit) .. '┴' - .. string.rep('─', w.limits) + .. string.rep('─', w.timeout) + .. '┴' + .. string.rep('─', w.memory) .. '┘' end @@ -160,7 +170,9 @@ local function flat_fence_above(c) .. '┴' .. string.rep('─', w.exit) .. '┴' - .. string.rep('─', w.limits) + .. string.rep('─', w.timeout) + .. '┴' + .. string.rep('─', w.memory) .. '┤' end @@ -175,7 +187,9 @@ local function flat_fence_below(c) .. '┬' .. string.rep('─', w.exit) .. '┬' - .. string.rep('─', w.limits) + .. string.rep('─', w.timeout) + .. '┬' + .. string.rep('─', w.memory) .. '┤' end @@ -194,7 +208,9 @@ local function header_line(c) .. '│' .. center('Exit Code', w.exit) .. '│' - .. center('Time (ms)/Mem (MB)', w.limits) + .. center('Time (ms)', w.timeout) + .. '│' + .. center('Mem (MB)', w.memory) .. '│' end @@ -205,12 +221,14 @@ local function data_row(c, idx, tc, is_current, test_state) local time = tc.time_ms and string.format('%.2f', tc.time_ms) or '—' local exit = format_exit_code(tc.code) - local limits = '' + local timeout = '' + local memory = '' if test_state.constraints then - limits = - string.format('%d/%.0f', test_state.constraints.timeout_ms, test_state.constraints.memory_mb) + timeout = tostring(test_state.constraints.timeout_ms) + memory = string.format('%.0f', test_state.constraints.memory_mb) else - limits = '—' + timeout = '—' + memory = '—' end local line = '│' @@ -222,13 +240,16 @@ local function data_row(c, idx, tc, is_current, test_state) .. '│' .. right_align(exit, w.exit) .. '│' - .. right_align(limits, w.limits) + .. right_align(timeout, w.timeout) + .. '│' + .. right_align(memory, w.memory) .. '│' local hi if status.text ~= '' then - local pad = w.status - #status.text - local status_start_col = 1 + w.num + 1 + pad + local content = ' ' .. status.text .. ' ' + local pad = w.status - #content + local status_start_col = 1 + w.num + 1 + pad + 1 local status_end_col = status_start_col + #status.text hi = { col_start = status_start_col, diff --git a/scrapers/codeforces.py b/scrapers/codeforces.py index db96804..7a1ecd4 100644 --- a/scrapers/codeforces.py +++ b/scrapers/codeforces.py @@ -7,7 +7,7 @@ from dataclasses import asdict import cloudscraper from bs4 import BeautifulSoup, Tag -from models import MetadataResult, ProblemSummary, TestCase, TestsResult +from scrapers.models import MetadataResult, ProblemSummary, TestCase, TestsResult def scrape(url: str) -> list[TestCase]: diff --git a/scrapers/cses.py b/scrapers/cses.py index 00cdc46..77fe64f 100755 --- a/scrapers/cses.py +++ b/scrapers/cses.py @@ -8,7 +8,7 @@ from dataclasses import asdict import requests from bs4 import BeautifulSoup, Tag -from models import MetadataResult, ProblemSummary, TestCase, TestsResult +from scrapers.models import MetadataResult, ProblemSummary, TestCase, TestsResult def parse_problem_url(problem_input: str) -> str | None: