@@ -17,6 +17,7 @@ local str = require('render-markdown.lib.str')
1717
1818--- @class render.md.table.Col
1919--- @field width integer
20+ --- @field delimiter_width integer
2021--- @field alignment render.md.table.col.Alignment
2122
2223--- @enum render.md.table.col.Alignment
@@ -185,17 +186,20 @@ function Render:compute_layout()
185186 local overhead = (num_cols + 1 ) + (num_cols * 2 * padding )
186187 local text_budget = available - overhead
187188
189+ --- @param cell render.md.table.row.Cell
190+ --- @return integer
191+ local function content_width (cell )
192+ return math.max (cell .width - cell .space .left - cell .space .right , 0 )
193+ end
194+
188195 -- Collect the natural text-area width for each column (max content width across all rows)
189196 local max_content = {} --- @type integer[]
190197 for i = 1 , num_cols do
191- max_content [i ] = math.max (
192- self .data .cols [i ].width - 2 * padding ,
193- self .config .min_width
194- )
198+ max_content [i ] = self .data .cols [i ].delimiter_width
195199 end
196200 for _ , row in ipairs (self .data .rows ) do
197201 for i , cell in ipairs (row .cells ) do
198- max_content [i ] = math.max (max_content [i ], cell . width )
202+ max_content [i ] = math.max (max_content [i ], content_width ( cell ) )
199203 end
200204 end
201205
@@ -233,35 +237,26 @@ function Render:compute_layout()
233237 col_widths [i ] = locked [i ] and max_content [i ] or math.max (share , 1 )
234238 end
235239
236- -- Compute per-row heights based on how many lines each cell needs.
237- -- Also account for the raw (unrendered) buffer line wrapping: if the source
238- -- text is longer than the rendered text (e.g. a long concealed URL), the
239- -- buffer line may wrap onto more screen lines than the rendered content
240- -- requires. We must cover all of those screen lines with overlay marks,
241- -- so the effective height is max(rendered_lines, raw_screen_lines).
240+ -- Compute per-row heights based on how many rendered lines each cell needs.
241+ -- Long delimiter cells can also force wrapping even when row contents fit.
242242 local row_heights = {} --- @type integer[]
243243 local needs_wrap = false
244+ for i , width in ipairs (max_content ) do
245+ needs_wrap = needs_wrap or width > col_widths [i ]
246+ end
244247 for r , row in ipairs (self .data .rows ) do
245248 local max_lines = 1
246249 for i , cell in ipairs (row .cells ) do
247250 local w = col_widths [i ]
248- if w > 0 and cell .width > w then
249- local lines = math.ceil (cell .width / w )
251+ local width = content_width (cell )
252+ if w > 0 and width > w then
253+ local lines = math.ceil (width / w )
250254 if lines > max_lines then
251255 max_lines = lines
252256 end
253257 needs_wrap = true
254258 end
255259 end
256- -- Raw buffer line screen-wrap: ceil(display_width_of_source / win_width)
257- local _ , line = row .node :line (' first' , 0 )
258- line = line or ' '
259- local raw_screen_lines =
260- math.max (1 , math.ceil (str .width (line ) / win_width ))
261- if raw_screen_lines > max_lines then
262- max_lines = raw_screen_lines
263- needs_wrap = true
264- end
265260 row_heights [r ] = max_lines
266261 end
267262
@@ -293,6 +288,7 @@ function Render:parse_cols(node)
293288 end
294289 cols [# cols + 1 ] = {
295290 width = width ,
291+ delimiter_width = math.max (width , self .config .min_width ),
296292 alignment = Render .alignment (cell ),
297293 }
298294 end
0 commit comments