@@ -308,24 +308,24 @@ function enable_virt(opts)
308308 local virt_lines_above = {}
309309 local virt_lines_below = {}
310310
311- if mult_virt_ns [buf ] then
312- vim .api .nvim_buf_clear_namespace ( buf , mult_virt_ns [ buf ], 0 , - 1 )
311+ if mult_virt_ns [buf ] == nil then
312+ mult_virt_ns [ buf ] = vim .api .nvim_create_namespace ( " nabla.nvim " )
313313 end
314- mult_virt_ns [buf ] = vim .api .nvim_create_namespace (" " )
315314
316315 local prev_row = - 1
317316 local prev_diff = 0
318317
319318 local next_prev_row
320319 local next_prev_diff
321320
322- local formula_nodes = utils .get_all_mathzones ()
321+ local formula_nodes = utils .get_all_mathzones (opts )
323322 local formulas_loc = {}
324323 for _ , node in ipairs (formula_nodes ) do
325324 local srow , scol , erow , ecol = ts_utils .get_node_range (node )
326- table.insert (formulas_loc , {srow , scol , erow , ecol })
325+ table.insert (formulas_loc , {srow , scol , erow , ecol })
327326 end
328327
328+ local conceal_padding = {}
329329 for _ , loc in ipairs (formulas_loc ) do
330330 local srow , scol , erow , ecol = unpack (loc )
331331 local succ , texts = pcall (vim .api .nvim_buf_get_text , buf , srow , scol , erow , ecol , {})
@@ -364,6 +364,40 @@ function enable_virt(opts)
364364
365365
366366
367+ if not conceal_padding [srow ] then
368+ -- account for treesitter capture conceals
369+ conceal_padding [srow ] = vim .iter (vim .gsplit (vim .api .nvim_buf_get_lines (0 , srow , srow + 1 , false )[1 ], ' ' ))
370+ :fold ({}, function (acc , _ )
371+ local conceal_cap = vim .iter (vim .treesitter .get_captures_at_pos (0 , srow , # acc ))
372+ :filter (function (v )
373+ return v .metadata .conceal
374+ end ):next ()
375+ acc [# acc + 1 ] = (# acc == 0 and 0 or acc [# acc ]) + 1 - (conceal_cap and vim .fn .strutf16len (conceal_cap .metadata .conceal ) or 1 )
376+ return acc
377+ end )
378+
379+ local marks = vim .iter (vim .api .nvim_buf_get_extmarks (0 , - 1 , { srow , 0 }, { srow , - 1 }, { details = true , }))
380+ local last_stat = marks :filter (function (v ) return v [4 ].virt_text and v [4 ].virt_text_pos == " inline" end )
381+ :fold ({0 , 0 }, function (stat , mark )
382+ if stat [1 ] >= mark [3 ] then
383+ return { stat [1 ], stat [2 ] + vim .iter (mark [4 ].virt_text ):fold (0 , function (len , v )
384+ -- the third term accounts for replacement of a character with virt_text (1) vs addition of string (0)
385+ return len + vim .fn .strutf16len (v [1 ]) - 1
386+ end ) }
387+ end
388+ for i = stat [1 ] + 1 , mark [3 ] + 1 do
389+ conceal_padding [srow ][i ] = conceal_padding [srow ][i ] - stat [2 ]
390+ end
391+ return {mark [3 ] + 1 ,
392+ stat [2 ] + vim .iter (mark [4 ].virt_text ):fold (0 , function (len , v )
393+ return len + vim .fn .strutf16len (v [1 ]) - 1
394+ end )}
395+ end )
396+ for i = last_stat [1 ] + 1 , # conceal_padding [srow ] do
397+ conceal_padding [srow ][i ] = conceal_padding [srow ][i ] - last_stat [2 ]
398+ end
399+ end
400+
367401 local drawing_virt = {}
368402
369403 for j = 1 ,# drawing do
@@ -469,7 +503,7 @@ function enable_virt(opts)
469503 end
470504
471505 local col = # vline
472- local padding = desired_col - col
506+ local padding = desired_col - col - conceal_padding [ srow ][ desired_col + 1 ]
473507 if prev_row == srow then
474508 padding = padding - prev_diff
475509 end
@@ -533,6 +567,7 @@ function enable_virt(opts)
533567 end
534568
535569 -- @place_drawings_above_lines
570+ local cleared_extmarks = {}
536571 for _ , conceal in ipairs (inline_virt ) do
537572 local chunks , row , p1 , p2 = unpack (conceal )
538573
@@ -543,6 +578,11 @@ function enable_virt(opts)
543578 end
544579
545580 if p1 + j <= p2 then
581+ if cleared_extmarks [row ] == nil then
582+ vim .api .nvim_buf_clear_namespace (buf , mult_virt_ns [buf ], row , row + 1 )
583+ cleared_extmarks [row ] = true
584+ end
585+
546586 vim .api .nvim_buf_set_extmark (buf , mult_virt_ns [buf ], row , p1 + j - 1 , {
547587 -- virt_text = {{ c, hl_group }},
548588 end_row = row ,
@@ -563,6 +603,11 @@ function enable_virt(opts)
563603 end
564604
565605 if # virt_lines_reversed > 0 then
606+ if cleared_extmarks [row ] == nil then
607+ vim .api .nvim_buf_clear_namespace (buf , mult_virt_ns [buf ], row , row + 1 )
608+ cleared_extmarks [row ] = true
609+ end
610+
566611 vim .api .nvim_buf_set_extmark (buf , mult_virt_ns [buf ], row , 0 , {
567612 virt_lines = virt_lines_reversed ,
568613 virt_lines_above = true ,
@@ -572,6 +617,11 @@ function enable_virt(opts)
572617
573618 for row , virt_lines in pairs (virt_lines_below ) do
574619 if # virt_lines > 0 then
620+ if cleared_extmarks [row ] == nil then
621+ vim .api .nvim_buf_clear_namespace (buf , mult_virt_ns [buf ], row , row + 1 )
622+ cleared_extmarks [row ] = true
623+ end
624+
575625 vim .api .nvim_buf_set_extmark (buf , mult_virt_ns [buf ], row , 0 , {
576626 virt_lines = virt_lines ,
577627 })
@@ -586,10 +636,10 @@ function enable_virt(opts)
586636
587637 local win = vim .api .nvim_get_current_win ()
588638 saved_wrapsettings [win ] = vim .wo [win ].wrap
589- vim .wo [win ].wrap = false
639+ -- vim.wo[win].wrap = false
590640
591641 if opts and opts .autogen then
592- autogen_autocmd [buf ] = vim .api .nvim_create_autocmd ({" InsertLeave" }, {
642+ autogen_autocmd [buf ] = vim .api .nvim_create_autocmd ({" InsertLeave" , " TextChanged " }, {
593643 buffer = buf ,
594644 desc = " nabla.nvim: Regenerates virt_lines automatically when the user exists insert mode" ,
595645 callback = function ()
0 commit comments