@@ -462,15 +462,14 @@ end
462462
463463--- @protected
464464function Render :run ()
465- self :delimiter ()
466465 if self .layout .wrap then
467- for r , row in ipairs ( self . data . rows ) do
468- self : row_wrapped ( row , r )
469- end
470- else
471- for _ , row in ipairs ( self . data . rows ) do
472- self : row ( row )
473- end
466+ self : wrapped ()
467+ return
468+ end
469+
470+ self : delimiter ()
471+ for _ , row in ipairs ( self . data . rows ) do
472+ self : row ( row )
474473 end
475474 if self .config .border_enabled and self .data .layout .valid then
476475 self :border ()
603602--- @private
604603--- @param row render.md.table.Row
605604--- @param row_index integer
606- function Render :row_wrapped (row , row_index )
605+ --- @return render.md.Line[]
606+ function Render :row_wrapped_lines (row , row_index )
607607 local height = self .layout .row_heights [row_index ]
608608 local header = row .node .type == ' pipe_table_header'
609609 local highlight = header and self .config .head or self .config .row
@@ -619,7 +619,8 @@ function Render:row_wrapped(row, row_index)
619619 end
620620
621621 local filler = self .config .filler
622- local function build_line (visual_line )
622+ local result = {} --- @type render.md.Line[]
623+ for visual_line = 0 , height - 1 do
623624 local line = self :line ()
624625 line :pad (spaces , filler )
625626 for i , _ in ipairs (self .data .cols ) do
@@ -637,72 +638,100 @@ function Render:row_wrapped(row, row_index)
637638 line :pad (padding , filler )
638639 end
639640 line :text (border_icon , highlight )
640- return line
641+ result [ # result + 1 ] = line
641642 end
643+ return result
644+ end
642645
643- local _ , buf_line = row .node :line (' first' , 0 )
644- buf_line = buf_line or ' '
645- local win_width = env .win .width (self .context .win )
646- local buf_screen_lines =
647- math.max (1 , math.ceil (str .width (buf_line ) / win_width ))
648-
649- -- Line 0: conceal the source line then overlay the rendered row on top.
650- if # buf_line > 0 then
651- self .marks :add (self .config , ' table_border' , row .node .start_row , 0 , {
652- end_row = row .node .start_row ,
653- end_col = # buf_line ,
654- conceal = ' ' ,
655- })
646+ --- @private
647+ function Render :wrapped ()
648+ local visual = {} --- @type render.md.Line[]
649+ for r , row in ipairs (self .data .rows ) do
650+ vim .list_extend (visual , self :row_wrapped_lines (row , r ))
651+ if r == 1 then
652+ visual [# visual + 1 ] = self :delimiter_line (self :delimiter_text ())
653+ end
656654 end
657- local first_line = build_line (0 )
658- self .marks :add (self .config , ' table_border' , row .node .start_row , 0 , {
659- virt_text = first_line :get (),
660- virt_text_pos = ' overlay' ,
661- hl_mode = ' combine' ,
662- })
655+ if self .config .border_enabled then
656+ if # self .data .rows > 1 then
657+ visual [# visual + 1 ] = self :border_line (false )
658+ end
663659
664- -- Lines 1..height-1: overlay buffer wrap continuations, then virt_lines.
665- local virt_lines = {} --- @type render.md.mark.Line[]
666- for vl = 1 , height - 1 do
667- if vl < buf_screen_lines then
668- local byte_col = vim .fn .byteidx (buf_line , vl * win_width )
660+ local first = self .data .rows [1 ].node
661+ local line = self :border_line (true )
662+ local row , target = first :line (' above' , 1 )
663+ if
664+ target
665+ and str .width (target ) == 0
666+ and self .context .used :take (row )
667+ then
668+ self .marks :add (self .config , ' table_border' , row , 0 , {
669+ virt_text = line :get (),
670+ virt_text_pos = ' overlay' ,
671+ })
672+ else
673+ self .marks :add (self .config , ' virtual_lines' , first .start_row , 0 , {
674+ virt_lines = { self :indent ():line (true ):extend (line ):get () },
675+ virt_lines_above = true ,
676+ })
677+ end
678+ end
679+
680+ local nodes = { self .data .rows [1 ].node , self .data .delim } --- @type render.md.Node[]
681+ for i = 2 , # self .data .rows do
682+ nodes [# nodes + 1 ] = self .data .rows [i ].node
683+ end
684+
685+ local win_width = env .win .width (self .context .win )
686+ local slots = {} --- @type { row : integer , col : integer } []
687+ for _ , node in ipairs (nodes ) do
688+ local _ , buf_line = node :line (' first' , 0 )
689+ buf_line = buf_line or ' '
690+ if # buf_line > 0 then
691+ self .marks :add (self .config , ' table_border' , node .start_row , 0 , {
692+ end_row = node .start_row ,
693+ end_col = # buf_line ,
694+ conceal = ' ' ,
695+ })
696+ end
697+ local screen_lines =
698+ math.max (math.ceil (str .width (buf_line ) / win_width ), 1 )
699+ for line = 0 , screen_lines - 1 do
700+ local byte_col = line == 0 and 0
701+ or vim .fn .byteidx (buf_line , line * win_width )
669702 if byte_col < 0 then
670703 byte_col = # buf_line
671704 end
672- if # virt_lines > 0 then
673- self .marks :add (
674- self .config ,
675- ' virtual_lines' ,
676- row .node .start_row ,
677- 0 ,
678- {
679- virt_lines = virt_lines ,
680- virt_lines_above = false ,
681- }
682- )
683- virt_lines = {}
684- end
685- self .marks :add (
686- self .config ,
687- ' table_border' ,
688- row .node .start_row ,
689- byte_col ,
690- {
691- virt_text = build_line (vl ):get (),
692- virt_text_pos = ' overlay' ,
693- hl_mode = ' combine' ,
694- }
695- )
705+ slots [# slots + 1 ] = { row = node .start_row , col = byte_col }
706+ end
707+ end
708+
709+ local virt_lines = {} --- @type render.md.mark.Line[]
710+ for i , line in ipairs (visual ) do
711+ local slot = slots [i ]
712+ if slot then
713+ self .marks :add (self .config , ' table_border' , slot .row , slot .col , {
714+ virt_text = line :get (),
715+ virt_text_pos = ' overlay' ,
716+ hl_mode = ' combine' ,
717+ })
696718 else
697- local vline = self : indent (): line ( true ): extend ( build_line ( vl ))
698- virt_lines [ # virt_lines + 1 ] = vline :get ()
719+ virt_lines [ # virt_lines + 1 ] =
720+ self : indent (): line ( true ): extend ( line ) :get ()
699721 end
700722 end
701723 if # virt_lines > 0 then
702- self .marks :add (self .config , ' virtual_lines' , row .node .start_row , 0 , {
703- virt_lines = virt_lines ,
704- virt_lines_above = false ,
705- })
724+ local last = self .data .rows [# self .data .rows ].node
725+ self .marks :add (
726+ self .config ,
727+ ' virtual_lines' ,
728+ last .start_row ,
729+ last .end_col ,
730+ {
731+ virt_lines = virt_lines ,
732+ virt_lines_above = false ,
733+ }
734+ )
706735 end
707736end
708737
0 commit comments