Skip to content

Commit ff577b4

Browse files
feat: use physical lines for table border if possible
## Details Much like with heading borders, attempt to use physical lines if they are empty, rather than always creating virtual lines. This is the new default behavior, `pipe_table.border_virtual = true` can be set to revert to the old behavior. This logic does conflict with the indentation module, specifically in that the definition of the range a specific section occupies is built around headings and their borders, and tables would conflict with this, leading to lines being at the incorrect indentation level. Rather than trying something overly complicated where sections continue to own the last empty line within themselves if that line belongs to a pipe table, the `border_virtual` option is set to `true` if the indent module is enabled, regardless of what the user has configured. Minor other changes: - When concealing text write functions that always take the full range - Add a `used` module inside context to store which lines are occupied by any render for the request, replaces the `last_heading` field - Use shorter `col` naming convention in table render rather than full `column` name - Assert width of table cells >= 0 rather than handling these cases, it should be impossible
1 parent b4016e8 commit ff577b4

20 files changed

+320
-323
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,9 @@ require('render-markdown').setup({
655655
'', '', '',
656656
'', '',
657657
},
658+
-- Always use virtual lines for table borders instead of attempting to use empty lines.
659+
-- Will be automatically enabled if indentation module is enabled.
660+
border_virtual = false,
658661
-- Gets placed in delimiter row for each column, position is based on alignment.
659662
alignment_indicator = '',
660663
-- Highlight for table heading, delimiter, and the line above.
@@ -1322,6 +1325,9 @@ require('render-markdown').setup({
13221325
'', '', '',
13231326
'', '',
13241327
},
1328+
-- Always use virtual lines for table borders instead of attempting to use empty lines.
1329+
-- Will be automatically enabled if indentation module is enabled.
1330+
border_virtual = false,
13251331
-- Gets placed in delimiter row for each column, position is based on alignment.
13261332
alignment_indicator = '',
13271333
-- Highlight for table heading, delimiter, and the line above.

benches/medium_table_spec.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ describe('medium-table.md', function()
99
util.num_marks(base_marks)
1010

1111
util.less_than(util.move_down(1), 0.5)
12-
util.num_marks(base_marks + 2)
12+
util.num_marks(base_marks + 1)
1313

1414
util.less_than(util.insert_mode(), 15)
15-
util.num_marks(base_marks + 2)
15+
util.num_marks(base_marks + 1)
1616
end)
1717
end)

doc/render-markdown.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For NVIM v0.11.1 Last change: 2025 May 05
1+
*render-markdown.txt* For NVIM v0.11.1 Last change: 2025 May 06
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*
@@ -720,6 +720,9 @@ Default Configuration ~
720720
'└', '┴', '┘',
721721
'│', '─',
722722
},
723+
-- Always use virtual lines for table borders instead of attempting to use empty lines.
724+
-- Will be automatically enabled if indentation module is enabled.
725+
border_virtual = false,
723726
-- Gets placed in delimiter row for each column, position is based on alignment.
724727
alignment_indicator = '━',
725728
-- Highlight for table heading, delimiter, and the line above.
@@ -1371,6 +1374,9 @@ Table Configuration ~
13711374
'└', '┴', '┘',
13721375
'│', '─',
13731376
},
1377+
-- Always use virtual lines for table borders instead of attempting to use empty lines.
1378+
-- Will be automatically enabled if indentation module is enabled.
1379+
border_virtual = false,
13741380
-- Gets placed in delimiter row for each column, position is based on alignment.
13751381
alignment_indicator = '━',
13761382
-- Highlight for table heading, delimiter, and the line above.

lua/render-markdown/config/pipe_table.lua

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
---@field padding integer
66
---@field min_width integer
77
---@field border string[]
8+
---@field border_virtual boolean
89
---@field alignment_indicator string
910
---@field head string
1011
---@field row string
@@ -72,6 +73,9 @@ M.default = {
7273
'', '', '',
7374
'', '',
7475
},
76+
-- Always use virtual lines for table borders instead of attempting to use empty lines.
77+
-- Will be automatically enabled if indentation module is enabled.
78+
border_virtual = false,
7579
-- Gets placed in delimiter row for each column, position is based on alignment.
7680
alignment_indicator = '',
7781
-- Highlight for table heading, delimiter, and the line above.
@@ -92,6 +96,7 @@ function M.validate(spec)
9296
spec:type('padding', 'number')
9397
spec:type('min_width', 'number')
9498
spec:list('border', 'string')
99+
spec:type('border_virtual', 'boolean')
95100
spec:type('alignment_indicator', 'string')
96101
spec:type('head', 'string')
97102
spec:type('row', 'string')

lua/render-markdown/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ local state = require('render-markdown.state')
55
local M = {}
66

77
---@private
8-
M.version = '8.3.28'
8+
M.version = '8.3.29'
99

1010
function M.check()
1111
M.start('version')

lua/render-markdown/init.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ end
124124
function M.resolve_config(user)
125125
local preset = require('render-markdown.lib.presets').get(user)
126126
local config = vim.tbl_deep_extend('force', M.default, preset, user)
127+
-- section indentation is built to support headings
128+
if config.indent.enabled then
129+
config.pipe_table.border_virtual = true
130+
end
127131
-- override settings that require neovim >= 0.10.0 and have compatible alternatives
128132
local has_10 = require('render-markdown.lib.compat').has_10
129133
if not has_10 then

lua/render-markdown/render/inline/highlight.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,24 +19,25 @@ end
1919
function Render:run()
2020
for _, range in ipairs(self.node:find('==[^=]+==')) do
2121
-- hide first 2 equal signs
22-
self:hide_equals(range[1], range[2])
22+
self:hide(range[1], range[2], range[2] + 2)
2323
-- highlight contents
2424
self.marks:add(false, range[1], range[2], {
2525
end_row = range[3],
2626
end_col = range[4],
2727
hl_group = self.config.highlight,
2828
})
2929
-- hide last 2 equal signs
30-
self:hide_equals(range[3], range[4] - 2)
30+
self:hide(range[3], range[4] - 2, range[4])
3131
end
3232
end
3333

3434
---@private
3535
---@param row integer
36-
---@param col integer
37-
function Render:hide_equals(row, col)
38-
self.marks:add(true, row, col, {
39-
end_col = col + 2,
36+
---@param start_col integer
37+
---@param end_col integer
38+
function Render:hide(row, start_col, end_col)
39+
self.marks:add(true, row, start_col, {
40+
end_col = end_col,
4041
conceal = '',
4142
})
4243
end

lua/render-markdown/render/inline/link.lua

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,18 @@ function Render:run()
4949
virt_text_pos = 'inline',
5050
})
5151
if self.data.autolink then
52-
self:hide_bracket(self.node.start_col)
52+
self:hide(self.node.start_col, self.node.start_col + 1)
5353
self.marks:over('link', self.node, { hl_group = self.data.icon[2] })
54-
self:hide_bracket(self.node.end_col - 1)
54+
self:hide(self.node.end_col - 1, self.node.end_col)
5555
end
5656
end
5757

5858
---@private
59-
---@param col integer
60-
function Render:hide_bracket(col)
61-
self.marks:add(true, self.node.start_row, col, {
62-
end_col = col + 1,
59+
---@param start_col integer
60+
---@param end_col integer
61+
function Render:hide(start_col, end_col)
62+
self.marks:add(true, self.node.start_row, start_col, {
63+
end_col = end_col,
6364
conceal = '',
6465
})
6566
end

lua/render-markdown/render/markdown/checkbox.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ end
5959
---@protected
6060
function Render:run()
6161
self:marker()
62-
self:icon()
62+
self:checkbox()
6363
self:scope()
6464
end
6565

@@ -72,7 +72,7 @@ function Render:marker()
7272
end
7373

7474
---@private
75-
function Render:icon()
75+
function Render:checkbox()
7676
local node = self.data.checkbox
7777
local line = self:line():text(self.data.icon, self.data.highlight)
7878
local space = self.context:width(node) + 1 - Str.width(self.data.icon)

lua/render-markdown/render/markdown/code.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ function Render:run()
8181
self.marks:over(true, bottom, { conceal = '' })
8282

8383
local icon = self:language(language, top)
84-
local more_info = info and language and info.end_col > language.end_col
85-
self:border(top, true, not icon and not more_info)
84+
local has_more = info and language and info.end_col > language.end_col
85+
self:border(top, true, not icon and not has_more)
8686
self:border(bottom, false, true)
8787

8888
local background = self:background_enabled(language)

lua/render-markdown/render/markdown/heading.lua

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ end
100100
---@protected
101101
function Render:run()
102102
self:sign(self.config.sign, self.data.sign, self.data.fg)
103-
local box = self:box(self:icon())
103+
local box = self:box(self:marker())
104104
self:background(box)
105105
self:padding(box)
106106
if self.data.atx then
@@ -114,7 +114,7 @@ end
114114

115115
---@private
116116
---@return integer
117-
function Render:icon()
117+
function Render:marker()
118118
local icon, highlight = self.data.icon, {}
119119
if self.data.fg then
120120
highlight[#highlight + 1] = self.data.fg
@@ -183,10 +183,10 @@ function Render:icon()
183183
end
184184

185185
---@private
186-
---@param icon integer
186+
---@param marker_width integer
187187
---@return render.md.heading.Box
188-
function Render:box(icon)
189-
local width = icon
188+
function Render:box(marker_width)
189+
local width = marker_width
190190
if self.data.atx then
191191
width = width + self.context:width(self.node:child('inline'))
192192
else
@@ -273,12 +273,11 @@ function Render:border(box, above)
273273
local row, target = self.node:line(above and 'above' or 'below', 1)
274274
local available = target and Str.width(target) == 0
275275

276-
if not virtual and available and row ~= self.context.last_heading then
276+
if not virtual and available and self.context.used:take(row) then
277277
self.marks:add('head_border', row, 0, {
278278
virt_text = line:get(),
279279
virt_text_pos = 'overlay',
280280
})
281-
self.context.last_heading = row
282281
else
283282
self.marks:add(false, self.node.start_row, 0, {
284283
virt_lines = {

0 commit comments

Comments
 (0)