From 018386ed1a0df33e235da65f8c44a319e63688c9 Mon Sep 17 00:00:00 2001 From: Immanuel Haffner Date: Fri, 3 Jul 2026 22:26:39 +0000 Subject: [PATCH] fix(renderer): use visual width for table wrap check The table wrap check used vim_width (raw text width including concealed content like URLs) to decide whether to skip rendering. This caused tables with long hyperlinks to not render at all when wrap is enabled, even though the visual width after conceal was well within the window. The whole table lost its padding and borders, so column-2 right borders appeared shifted far off, worsening with URL length. Use col_widths (visual width after conceal resolution) instead, which correctly reflects the rendered table width. Add test/table_wrap_link_border.md as a visual repro (wrap enabled, long URLs in cells); every column-2 right border must align once the cursor is off the table and the URLs conceal. --- lua/markview/renderers/markdown.lua | 7 ++++- test/table_wrap_link_border.md | 46 +++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 test/table_wrap_link_border.md diff --git a/lua/markview/renderers/markdown.lua b/lua/markview/renderers/markdown.lua index 4925edf6..f7f46178 100644 --- a/lua/markview/renderers/markdown.lua +++ b/lua/markview/renderers/markdown.lua @@ -1658,7 +1658,12 @@ markdown.table = function (buffer, item) local table_width = 1; - for _, col in ipairs(vim_width) do + --- NOTE: Use the VISIBLE column widths (post-conceal) here, not the raw + --- `vim_width`. `vim_width` includes concealed content such as the full + --- `](https://…)` of a link, so a table cell with a long URL would make + --- `table_width` exceed the window and skip rendering entirely, leaving + --- the row with no padding/borders and a badly shifted right border. + for _, col in ipairs(col_widths) do table_width = table_width + 1 + col; end diff --git a/test/table_wrap_link_border.md b/test/table_wrap_link_border.md new file mode 100644 index 00000000..eb193591 --- /dev/null +++ b/test/table_wrap_link_border.md @@ -0,0 +1,46 @@ +; Long links in table cells — right border shifts off when `wrap` is on + +When a table cell contains a link (`[text](url)`) or image, the renderer conceals +the `](https://…)` portion, so the *visible* cell is only as wide as the label +plus the link icon (e.g. `󰌷 label`). The column-width calculation in +`renderers/markdown/tostring.lua` correctly measures this concealed width and +stores it in `col_widths`. + +However, with `wrap` enabled the table renderer runs a "is this table too wide to +bother rendering?" guard. That guard summed the RAW column widths (`vim_width`), +which include the *unconcealed* URL — often 90+ columns for a real link. A single +long-URL cell therefore made the estimated table width exceed the window and the +renderer bailed out completely (`return`), drawing NO padding and NO borders for +the whole table. The visible `|` characters are then just the raw trailing pipes +of each source line, landing at wildly different columns per row, so the right +border appears shifted far off — and the longer the URL, the further it drifts. + +Fix: base the width guard on `col_widths` (the visible, post-conceal widths) +instead of `vim_width` (the raw widths). Long-URL tables whose concealed width +fits the window then render with correct padding and aligned borders. + +To reproduce, open this file (its modeline enables `wrap`) in a window that is +comfortably wider than the *concealed* table but narrower than the *raw* table +(the long URLs are much wider than the visible cells). Move the cursor OFF the +table so the URLs conceal. Every right border of column 2 must line up in a +single straight vertical column; the short-URL and long-URL rows must agree. + +### Long hyperlink URLs (primary repro) + +| Kind | Link | +|-------------|--------------------------------------------------------------------------------------------------| +| Hyperlink | [Neovim API reference](https://neovim.io/doc/user/api.html#nvim_buf_set_extmark()-full-details) | +| Image | ![screenshot](https://raw.githubusercontent.com/nvim-treesitter/playground/master/screenshot.png) | +| Bold + link | **[bold link with long URL](https://spec.commonmark.org/0.31.2/#emphasis-and-strong-emphasis)** | +| Short (ctl) | [ref](https://a.co) | +| Plain (ctl) | no link here | + +### Mixed short/long links (borders must still align) + +| Name | Reference | +|--------|--------------------------------------------------------------------------------------------| +| short | [a](https://a.co) | +| medium | [docs](https://example.com/some/moderately/long/path/to/a/page.html) | +| long | [spec](https://spec.commonmark.org/0.31.2/#emphasis-and-strong-emphasis-combined-with-links) | + +