@@ -103,20 +103,27 @@ M.render_node = function(namespace, buf, capture, node)
103
103
if not util .has_10 then
104
104
return
105
105
end
106
- -- Fenced code blocks will pick up varying amounts of leading white space depending on
107
- -- the context they are in. This gets lumped into the delimiter node and as a result,
108
- -- after concealing, the extmark will be left shifted. Logic below accounts for this.
109
- local padding = 0
110
- local code_block = ts .parent_in_section (info .node , ' fenced_code_block' )
111
- if code_block ~= nil then
112
- padding = str .leading_spaces (ts .info (code_block , buf ).text )
106
+
107
+ local icon_text = icon .. ' '
108
+ if ts .concealed (buf , info ) > 0 then
109
+ -- Fenced code blocks will pick up varying amounts of leading white space depending on
110
+ -- the context they are in. This gets lumped into the delimiter node and as a result,
111
+ -- after concealing, the extmark will be left shifted. Logic below accounts for this.
112
+ local padding = 0
113
+ local code_block = ts .parent_in_section (info .node , ' fenced_code_block' )
114
+ if code_block ~= nil then
115
+ padding = str .leading_spaces (ts .info (code_block , buf ).text )
116
+ end
117
+ icon_text = str .pad (icon_text .. info .text , padding )
113
118
end
119
+
114
120
local highlight = { icon_highlight }
115
121
if code .style == ' full' then
116
122
highlight = { icon_highlight , code .highlight }
117
123
end
124
+
118
125
vim .api .nvim_buf_set_extmark (buf , namespace , info .start_row , info .start_col , {
119
- virt_text = { { str . pad ( icon .. ' ' .. info . text , padding ) , highlight } },
126
+ virt_text = { { icon_text , highlight } },
120
127
virt_text_pos = ' inline' ,
121
128
})
122
129
elseif capture == ' list_marker' then
@@ -220,31 +227,19 @@ M.render_node = function(namespace, buf, capture, node)
220
227
return
221
228
end
222
229
223
- --- @param row integer
224
- --- @param s string
225
- --- @return integer
226
- local function get_row_width (row , s )
227
- local result = vim .fn .strdisplaywidth (s )
228
- if pipe_table .cell == ' raw' then
229
- result = result - ts .concealed (buf , row , s )
230
- end
231
- return result
232
- end
233
-
234
230
local delim = ts .info (delim_node , buf )
235
- local delim_width = get_row_width (delim .start_row , delim .text )
236
-
237
231
local lines = vim .api .nvim_buf_get_lines (buf , info .start_row , info .end_row , true )
238
- local start_width = get_row_width (info .start_row , list .first (lines ))
239
- local end_width = get_row_width (info .end_row - 1 , list .last (lines ))
240
232
233
+ local delim_width = vim .fn .strdisplaywidth (delim .text )
234
+ local start_width = vim .fn .strdisplaywidth (list .first (lines ))
235
+ local end_width = vim .fn .strdisplaywidth (list .last (lines ))
241
236
if delim_width ~= start_width or start_width ~= end_width then
242
237
return
243
238
end
244
239
245
240
local headings = vim .split (delim .text , ' |' , { plain = true , trimempty = true })
246
- local lengths = vim .tbl_map (function (part )
247
- return border [11 ]:rep (vim .fn .strdisplaywidth (part ))
241
+ local lengths = vim .tbl_map (function (cell )
242
+ return border [11 ]:rep (vim .fn .strdisplaywidth (cell ))
248
243
end , headings )
249
244
250
245
local line_above = border [1 ] .. table.concat (lengths , border [2 ]) .. border [3 ]
@@ -278,30 +273,6 @@ M.render_node = function(namespace, buf, capture, node)
278
273
})
279
274
end
280
275
281
- --- @param row_info render.md.NodeInfo
282
- --- @param highlight string
283
- local function render_table_row (row_info , highlight )
284
- if pipe_table .cell == ' overlay' then
285
- vim .api .nvim_buf_set_extmark (buf , namespace , row_info .start_row , row_info .start_col , {
286
- end_row = row_info .end_row ,
287
- end_col = row_info .end_col ,
288
- virt_text = { { row_info .text :gsub (' |' , border [10 ]), highlight } },
289
- virt_text_pos = ' overlay' ,
290
- })
291
- elseif pipe_table .cell == ' raw' then
292
- for i = 1 , # row_info .text do
293
- if row_info .text :sub (i , i ) == ' |' then
294
- vim .api .nvim_buf_set_extmark (buf , namespace , row_info .start_row , i - 1 , {
295
- end_row = row_info .end_row ,
296
- end_col = i - 1 ,
297
- virt_text = { { border [10 ], highlight } },
298
- virt_text_pos = ' overlay' ,
299
- })
300
- end
301
- end
302
- end
303
- end
304
-
305
276
if pipe_table .style == ' full' then
306
277
render_table_full ()
307
278
end
@@ -312,9 +283,9 @@ M.render_node = function(namespace, buf, capture, node)
312
283
if row_type == ' pipe_table_delimiter_row' then
313
284
render_table_delimiter (row_info )
314
285
elseif row_type == ' pipe_table_header' then
315
- render_table_row (row_info , pipe_table .head )
286
+ M . render_table_row (namespace , buf , row_info , pipe_table .head )
316
287
elseif row_type == ' pipe_table_row' then
317
- render_table_row (row_info , pipe_table .row )
288
+ M . render_table_row (namespace , buf , row_info , pipe_table .row )
318
289
else
319
290
-- Should only get here if markdown introduces more row types, currently unhandled
320
291
logger .error (' Unhandled markdown row type: ' .. row_type )
@@ -326,4 +297,65 @@ M.render_node = function(namespace, buf, capture, node)
326
297
end
327
298
end
328
299
300
+ --- @param namespace integer
301
+ --- @param buf integer
302
+ --- @param info render.md.NodeInfo
303
+ --- @param highlight string
304
+ M .render_table_row = function (namespace , buf , info , highlight )
305
+ --- @param text string
306
+ --- @return integer
307
+ local function inline_width (text )
308
+ local query = state .inline_link_query
309
+ local tree = vim .treesitter .get_string_parser (text , ' markdown_inline' )
310
+ local result = 0
311
+ for id in query :iter_captures (tree :parse ()[1 ]:root (), text ) do
312
+ if query .captures [id ] == ' link' then
313
+ result = result + vim .fn .strdisplaywidth (state .config .link .hyperlink )
314
+ end
315
+ end
316
+ return result
317
+ end
318
+
319
+ local pipe_table = state .config .pipe_table
320
+ local border = pipe_table .border
321
+
322
+ if vim .tbl_contains ({ ' raw' , ' padded' }, pipe_table .cell ) then
323
+ for cell in info .node :iter_children () do
324
+ local cell_info = ts .info (cell , buf )
325
+ local cell_type = cell_info .node :type ()
326
+ if cell_type == ' |' then
327
+ vim .api .nvim_buf_set_extmark (buf , namespace , cell_info .start_row , cell_info .start_col , {
328
+ end_row = cell_info .end_row ,
329
+ end_col = cell_info .end_col ,
330
+ virt_text = { { border [10 ], highlight } },
331
+ virt_text_pos = ' overlay' ,
332
+ })
333
+ elseif cell_type == ' pipe_table_cell' then
334
+ if pipe_table .cell == ' padded' then
335
+ -- Requires inline extmarks
336
+ if util .has_10 then
337
+ local concealed = ts .concealed (buf , cell_info ) - inline_width (cell_info .text )
338
+ if concealed > 0 then
339
+ vim .api .nvim_buf_set_extmark (buf , namespace , cell_info .start_row , cell_info .end_col , {
340
+ virt_text = { { str .pad (' ' , concealed ), pipe_table .filler } },
341
+ virt_text_pos = ' inline' ,
342
+ })
343
+ end
344
+ end
345
+ end
346
+ else
347
+ -- Should only get here if markdown introduces more cell types, currently unhandled
348
+ logger .error (' Unhandled markdown cell type: ' .. cell_type )
349
+ end
350
+ end
351
+ elseif pipe_table .cell == ' overlay' then
352
+ vim .api .nvim_buf_set_extmark (buf , namespace , info .start_row , info .start_col , {
353
+ end_row = info .end_row ,
354
+ end_col = info .end_col ,
355
+ virt_text = { { info .text :gsub (' |' , border [10 ]), highlight } },
356
+ virt_text_pos = ' overlay' ,
357
+ })
358
+ end
359
+ end
360
+
329
361
return M
0 commit comments