Skip to content

Commit 98a3b7d

Browse files
feat: bullet padding functions
## Details Request: #349 This allows both `bullet.left_pad` & `bullet.right_pad` to be a `function` that returns an `integer` in addition to the basic `integer` value. The input is the same `ctx` object that is provided to the `icon` `function` and currently contains the following fields: - `level`: how deeply nested the current list item is - `index`: the index of the list item within its bottom most list - `value`: the text value of the marker node, useful for ordered lists Unrelated change: `Base:padding_text()` -> `Base:pad()`
1 parent 33673e6 commit 98a3b7d

File tree

12 files changed

+85
-55
lines changed

12 files changed

+85
-55
lines changed

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.0.10'
8+
M.version = '8.0.11'
99

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

lua/render-markdown/init.lua

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,15 @@ local M = {}
159159
---| string[][]
160160
---| fun(ctx: render.md.BulletContext): string?
161161

162+
---@alias render.md.bullet.Padding
163+
---| integer
164+
---| fun(ctx: render.md.BulletContext): integer
165+
162166
---@class (exact) render.md.UserBullet: render.md.UserBaseComponent
163167
---@field public icons? render.md.bullet.Icons
164168
---@field public ordered_icons? render.md.bullet.Icons
165-
---@field public left_pad? integer
166-
---@field public right_pad? integer
169+
---@field public left_pad? render.md.bullet.Padding
170+
---@field public right_pad? render.md.bullet.Padding
167171
---@field public highlight? string
168172

169173
---@class (exact) render.md.UserDash: render.md.UserBaseComponent

lua/render-markdown/render/base.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,11 @@ function Base:indent_line(virtual, level)
9595
local indent = self.config.indent
9696
local icon_width = Str.width(indent.icon)
9797
if icon_width == 0 then
98-
table.insert(line, self:padding_text(indent.per_level * level))
98+
table.insert(line, self:pad(indent.per_level * level))
9999
else
100100
for _ = 1, level do
101101
table.insert(line, { indent.icon, indent.highlight })
102-
table.insert(line, self:padding_text(indent.per_level - icon_width))
102+
table.insert(line, self:pad(indent.per_level - icon_width))
103103
end
104104
end
105105
end
@@ -139,7 +139,7 @@ end
139139
---@param width integer
140140
---@param highlight? string
141141
---@return render.md.line.Text
142-
function Base:padding_text(width, highlight)
142+
function Base:pad(width, highlight)
143143
return { Str.pad(width), highlight or self.config.padding.highlight }
144144
end
145145

lua/render-markdown/render/code.lua

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ function Render:background(start_row, end_row)
203203
local win_col, padding = 0, {}
204204
if self.code.width == 'block' then
205205
win_col = self.data.margin + self.data.max_width + self.data.indent
206-
table.insert(padding, self:padding_text(vim.o.columns * 2))
206+
table.insert(padding, self:pad(vim.o.columns * 2))
207207
end
208208
for row = start_row, end_row do
209209
self.marks:add('code_background', row, self.data.col, {
@@ -233,9 +233,9 @@ function Render:left_pad(background)
233233
-- Use lowest priority (0) to include all other marks in padding when code block is at edge
234234
-- Use medium priority (1000) to include border marks while likely avoiding other plugin
235235
local priority = self.data.col == 0 and 0 or 1000
236-
local fill_text = self:padding_text(self.data.col)
237-
local margin_text = self:padding_text(margin)
238-
local padding_text = self:padding_text(padding, background and self.code.highlight or nil)
236+
local fill_text = self:pad(self.data.col)
237+
local margin_text = self:pad(margin)
238+
local padding_text = self:pad(padding, background and self.code.highlight or nil)
239239

240240
local start_row, end_row = self.node.start_row, (self.node.end_row - 1)
241241
for row = start_row, end_row do

lua/render-markdown/render/code_inline.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function Render:side_padding(highlight, row, col)
3333
if padding > 0 then
3434
self.marks:add(true, row, col, {
3535
priority = 0,
36-
virt_text = { self:padding_text(padding, highlight) },
36+
virt_text = { self:pad(padding, highlight) },
3737
virt_text_pos = 'inline',
3838
})
3939
end

lua/render-markdown/render/dash.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function Render:render()
2121

2222
local virt_text = {}
2323
if margin > 0 then
24-
table.insert(virt_text, self:padding_text(margin))
24+
table.insert(virt_text, self:pad(margin))
2525
end
2626
table.insert(virt_text, { self.dash.icon:rep(width), self.dash.highlight })
2727

lua/render-markdown/render/heading.lua

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ function Render:background(width)
207207
local win_col, padding = 0, {}
208208
if self.data.width == 'block' then
209209
win_col = width.margin + width.content + self:indent_size(self.data.level)
210-
table.insert(padding, self:padding_text(vim.o.columns * 2))
210+
table.insert(padding, self:pad(vim.o.columns * 2))
211211
end
212212
for row = self.node.start_row, self.node.end_row - 1 do
213213
self.marks:add('head_background', row, 0, {
@@ -238,11 +238,11 @@ function Render:border(width, position, icon, row)
238238

239239
local foreground = self.data.foreground
240240
local background = self.data.background and colors.bg_to_fg(self.data.background)
241-
local total_width = self.data.width == 'block' and width.content or vim.o.columns
242241
local prefix = self.heading.border_prefix and self.data.level or 0
242+
local total_width = self.data.width == 'block' and width.content or vim.o.columns
243243

244244
local line = {
245-
self:padding_text(width.margin),
245+
self:pad(width.margin),
246246
{ icon:rep(width.padding), background },
247247
{ icon:rep(prefix), foreground },
248248
{ icon:rep(total_width - width.padding - prefix), background },
@@ -271,10 +271,10 @@ end
271271
function Render:left_pad(width)
272272
local virt_text = {}
273273
if width.margin > 0 then
274-
table.insert(virt_text, self:padding_text(width.margin))
274+
table.insert(virt_text, self:pad(width.margin))
275275
end
276276
if width.padding > 0 then
277-
table.insert(virt_text, self:padding_text(width.padding, self.data.background))
277+
table.insert(virt_text, self:pad(width.padding, self.data.background))
278278
end
279279
if #virt_text == 0 then
280280
return

lua/render-markdown/render/list_item.lua

Lines changed: 59 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,17 @@ function Render:render()
4646
return
4747
end
4848
local level, root = self.node:level_in_section('list')
49-
self:icon(level)
50-
self:padding(root)
49+
---@type render.md.BulletContext
50+
local ctx = {
51+
level = level,
52+
index = self.node:sibling_count('list_item'),
53+
value = self.data.marker.text,
54+
}
55+
local icon = self:get_icon(ctx)
56+
local left_pad = self:get_padding(ctx, self.bullet.left_pad)
57+
local right_pad = self:get_padding(ctx, self.bullet.right_pad)
58+
self:add_icon(icon)
59+
self:add_padding(left_pad, right_pad, root)
5160
end
5261
end
5362

@@ -83,46 +92,63 @@ function Render:highlight_scope()
8392
end
8493

8594
---@private
86-
---@param level integer
87-
function Render:icon(level)
88-
local node = self.data.marker
89-
local index = self.node:sibling_count('list_item')
95+
---@param ctx render.md.BulletContext
96+
---@return string?
97+
function Render:get_icon(ctx)
9098
local icons = self.data.ordered and self.bullet.ordered_icons or self.bullet.icons
91-
local icon = nil
9299
if type(icons) == 'function' then
93-
icon = icons({ level = level, index = index, value = node.text })
100+
return icons(ctx)
94101
else
95-
icon = List.cycle(icons, level)
102+
local icon = List.cycle(icons, ctx.level)
96103
if type(icon) == 'table' then
97-
icon = List.clamp(icon, index)
104+
return List.clamp(icon, ctx.index)
105+
else
106+
return icon
98107
end
99108
end
109+
end
110+
111+
---@private
112+
---@param ctx render.md.BulletContext
113+
---@param pad render.md.bullet.Padding
114+
---@return integer
115+
function Render:get_padding(ctx, pad)
116+
if type(pad) == 'function' then
117+
return pad(ctx)
118+
else
119+
return pad
120+
end
121+
end
122+
123+
---@private
124+
---@param icon string?
125+
function Render:add_icon(icon)
100126
if icon == nil then
101127
return
102128
end
103129
local text = Str.pad(self.data.spaces) .. icon
104-
local position, conceal = 'overlay', nil
105-
if Str.width(text) > Str.width(node.text) then
106-
position, conceal = 'inline', ''
107-
end
108-
self.marks:add_over('bullet', node, {
130+
local overflow = Str.width(text) > Str.width(self.data.marker.text)
131+
self.marks:add_over('bullet', self.data.marker, {
109132
virt_text = { { text, self.bullet.highlight } },
110-
virt_text_pos = position,
111-
conceal = conceal,
133+
virt_text_pos = overflow and 'inline' or 'overlay',
134+
conceal = overflow and '' or nil,
112135
})
113136
end
114137

115138
---@private
139+
---@param left_pad integer
140+
---@param right_pad integer
116141
---@param root? render.md.Node
117-
function Render:padding(root)
118-
if self.bullet.left_pad <= 0 and self.bullet.right_pad <= 0 then
142+
function Render:add_padding(left_pad, right_pad, root)
143+
if left_pad <= 0 and right_pad <= 0 then
119144
return
120145
end
121-
local left_col = root ~= nil and root.start_col or self.node.start_col
122-
for row = self.node.start_row, self:end_row(root) - 1 do
123-
local right_col = row == self.node.start_row and self.data.marker.end_col - 1 or left_col
124-
self:padding_mark(row, left_col, self.bullet.left_pad)
125-
self:padding_mark(row, right_col, self.bullet.right_pad)
146+
local start_row, end_row = self.node.start_row, self:end_row(root)
147+
for row = start_row, end_row - 1 do
148+
local left_col = root ~= nil and root.start_col or self.node.start_col
149+
local right_col = row == start_row and self.data.marker.end_col - 1 or left_col
150+
self:side_padding(row, left_col, left_pad)
151+
self:side_padding(row, right_col, right_pad)
126152
end
127153
end
128154

@@ -133,26 +159,26 @@ function Render:end_row(root)
133159
local next_list = self.node:child('list')
134160
if next_list ~= nil then
135161
return next_list.start_row
136-
end
137-
local end_row = self.node.end_row
138-
-- On the last item of the root list ignore the last line if it is empty
139-
if root ~= nil and root.end_row == end_row then
140-
if Str.width(self.node:line('last', 0)) == 0 then
141-
return end_row - 1
162+
else
163+
local row = self.node.end_row
164+
-- On the last item of the root list ignore the last line if it is empty
165+
if root ~= nil and root.end_row == row and Str.width(root:line('last', 0)) == 0 then
166+
return row - 1
167+
else
168+
return row
142169
end
143170
end
144-
return end_row
145171
end
146172

147173
---@private
148174
---@param row integer
149175
---@param col integer
150176
---@param amount integer
151-
function Render:padding_mark(row, col, amount)
177+
function Render:side_padding(row, col, amount)
152178
if amount > 0 then
153179
self.marks:add(false, row, col, {
154180
priority = 0,
155-
virt_text = { self:padding_text(amount) },
181+
virt_text = { self:pad(amount) },
156182
virt_text_pos = 'inline',
157183
})
158184
end

lua/render-markdown/render/paragraph.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ function Render:render()
2727
return
2828
end
2929

30-
local virt_text = { self:padding_text(margin) }
30+
local virt_text = { self:pad(margin) }
3131
for row = self.node.start_row, self.node.end_row - 1 do
3232
self.marks:add(false, row, 0, {
3333
priority = 0,

lua/render-markdown/render/table.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,7 @@ function Render:full()
375375
---@param above boolean
376376
---@param chars { [1]: string, [2]: string, [3]: string }
377377
local function table_border(node, above, chars)
378-
local line = spaces > 0 and { self:padding_text(spaces) } or {}
378+
local line = spaces > 0 and { self:pad(spaces) } or {}
379379
local highlight = above and self.table.head or self.table.row
380380
table.insert(line, { chars[1] .. table.concat(sections, chars[2]) .. chars[3], highlight })
381381
self.marks:add_start(false, node, {

lua/render-markdown/state.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ function M.validate()
208208
end)
209209
:nested('bullet', function(bullet)
210210
component_rules(bullet)
211-
:type({ 'left_pad', 'right_pad' }, 'number')
211+
:type({ 'left_pad', 'right_pad' }, { 'number', 'function' })
212212
:type('highlight', 'string')
213213
:list_or_list_of_list({ 'icons', 'ordered_icons' }, 'string', 'function')
214214
:check()

lua/render-markdown/types.lua

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@
113113
---@class (exact) render.md.Bullet: render.md.BaseComponent
114114
---@field public icons render.md.bullet.Icons
115115
---@field public ordered_icons render.md.bullet.Icons
116-
---@field public left_pad integer
117-
---@field public right_pad integer
116+
---@field public left_pad render.md.bullet.Padding
117+
---@field public right_pad render.md.bullet.Padding
118118
---@field public highlight string
119119

120120
---@class (exact) render.md.Dash: render.md.BaseComponent

0 commit comments

Comments
 (0)