Skip to content

Commit ed3acd6

Browse files
chore(refactor): add general append method for line, replaces pad
## Details Add a helper method for creating more complex virtual text lines. Assumes `padding` if highlight is not provided, adds string of repeated spaces if number is provided, skips empty sections. Use throughout where helpful.
1 parent b56fa1b commit ed3acd6

14 files changed

+97
-99
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Features
66

7+
- in-process lsp for engine agnostic completions [b56fa1b](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/b56fa1bc7b513f16a1c361b81438f4944b420a32)
78
- customize heading properties based on text [#320](https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/320)
89
[5c2440d](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/5c2440d932a4ba96840e5ce5a7bd40f0624bdaa2)
910
- allow html tags to be replaced with icons [#336](https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/336)
@@ -40,6 +41,7 @@
4041
- @dsully
4142
- @mcDevnagh
4243
- @filippo-biondi
44+
- @Saecki (for in-process lsp inspiration)
4345

4446
## 8.0.0 (2025-02-06)
4547

doc/render-markdown.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.10.0 Last change: 2025 March 04
1+
*render-markdown.txt* For 0.10.0 Last change: 2025 March 07
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*

lua/render-markdown/health.lua

+1-1
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.20'
8+
M.version = '8.0.21'
99

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

lua/render-markdown/render/base.lua

+18-7
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ function Base:indent_line(virtual, level)
9292
local indent = self.config.indent
9393
local icon_width = Str.width(indent.icon)
9494
if icon_width == 0 then
95-
table.insert(line, self:pad(indent.per_level * level))
95+
self:append(line, indent.per_level * level)
9696
else
9797
for _ = 1, level do
98-
table.insert(line, { indent.icon, indent.highlight })
99-
table.insert(line, self:pad(indent.per_level - icon_width))
98+
self:append(line, indent.icon, indent.highlight)
99+
self:append(line, indent.per_level - icon_width)
100100
end
101101
end
102102
end
@@ -133,11 +133,22 @@ function Base:indent_level(level)
133133
end
134134

135135
---@protected
136-
---@param width integer
136+
---@param line render.md.Line
137+
---@param value string|integer
137138
---@param highlight? string|string[]
138-
---@return render.md.Text
139-
function Base:pad(width, highlight)
140-
return { Str.pad(width), highlight or self.config.padding.highlight }
139+
---@return render.md.Line
140+
function Base:append(line, value, highlight)
141+
highlight = highlight or self.config.padding.highlight
142+
if type(value) == 'string' then
143+
if #value > 0 then
144+
table.insert(line, { value, highlight })
145+
end
146+
else
147+
if value > 0 then
148+
table.insert(line, { Str.pad(value), highlight })
149+
end
150+
end
151+
return line
141152
end
142153

143154
return Base

lua/render-markdown/render/code.lua

+19-21
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ local colors = require('render-markdown.colors')
1212
---@field margin integer
1313
---@field language_padding integer
1414
---@field padding integer
15+
---@field width integer
1516
---@field max_width integer
1617
---@field empty_rows integer[]
1718
---@field indent integer
@@ -62,6 +63,7 @@ function Render:setup()
6263
margin = self:offset(self.code.left_margin, max_width, 'left'),
6364
language_padding = language_padding,
6465
padding = left_padding,
66+
width = self.code.width == 'block' and max_width or vim.o.columns,
6567
max_width = max_width,
6668
empty_rows = empty_rows,
6769
indent = self:indent_size(),
@@ -97,7 +99,7 @@ function Render:render()
9799

98100
local icon = self:language()
99101
local start_row, end_row = self.node.start_row, self.node.end_row - 1
100-
self:border(start_row, self.code.above, not icon and self:hidden(self.data.code_node))
102+
self:border(start_row, self.code.above, not icon and self:concealed(self.data.code_node))
101103
self:border(end_row, self.code.below, true)
102104
if background then
103105
self:background(start_row + 1, end_row - 1)
@@ -135,7 +137,7 @@ function Render:language()
135137
end
136138

137139
if self.code.position == 'left' then
138-
if self.code.language_name and self:hidden(node) then
140+
if self.code.language_name and self:concealed(node) then
139141
-- Code blocks pick up varying amounts of leading white space depending
140142
-- on the context they are in. This is lumped into the delimiter node
141143
-- and as a result, after concealing, the extmark would be shifted.
@@ -173,9 +175,9 @@ function Render:border(row, border, context_hidden)
173175
return
174176
end
175177
local delim_node = self.node:child('fenced_code_block_delimiter', row)
176-
if self.code.border == 'thin' and context_hidden and self:hidden(delim_node) then
177-
local width = self.code.width == 'block' and self.data.max_width or vim.o.columns
178-
local line = { { border:rep(width - self.data.col), colors.bg_to_fg(self.code.highlight) } }
178+
if self.code.border == 'thin' and context_hidden and self:concealed(delim_node) then
179+
local width = self.data.width - self.data.col
180+
local line = { { border:rep(width), colors.bg_to_fg(self.code.highlight) } }
179181
self.marks:add('code_border', row, self.data.col, {
180182
virt_text = line,
181183
virt_text_pos = 'overlay',
@@ -188,7 +190,7 @@ end
188190
---@private
189191
---@param node? render.md.Node
190192
---@return boolean
191-
function Render:hidden(node)
193+
function Render:concealed(node)
192194
-- TODO(0.11): handle conceal_lines
193195
-- - Use self.context:hidden(node) to determine if a node is hidden
194196
-- - Default highlights remove the fenced code block delimiter lines along with
@@ -214,7 +216,7 @@ function Render:background(start_row, end_row)
214216
local win_col, padding = 0, {}
215217
if self.code.width == 'block' then
216218
win_col = self.data.margin + self.data.max_width + self.data.indent
217-
table.insert(padding, self:pad(vim.o.columns * 2))
219+
self:append(padding, vim.o.columns * 2)
218220
end
219221
for row = start_row, end_row do
220222
self.marks:add('code_background', row, self.data.col, {
@@ -244,26 +246,22 @@ function Render:left_pad(background)
244246
-- Use lowest priority (0) to include all other marks in padding when code block is at edge
245247
-- Use medium priority (1000) to include border marks while likely avoiding other plugin
246248
local priority = self.data.col == 0 and 0 or 1000
247-
local fill_text = self:pad(self.data.col)
248-
local margin_text = self:pad(margin)
249-
local padding_text = self:pad(padding, background and self.code.highlight or nil)
249+
local highlight = background and self.code.highlight or nil
250250

251-
local start_row, end_row = self.node.start_row, (self.node.end_row - 1)
251+
local start_row, end_row = self.node.start_row, self.node.end_row - 1
252252
for row = start_row, end_row do
253-
local virt_text = {}
254-
if self.data.col > 0 and vim.tbl_contains(self.data.empty_rows, row) then
255-
table.insert(virt_text, fill_text)
256-
end
257-
if margin > 0 then
258-
table.insert(virt_text, margin_text)
253+
local line = {}
254+
if vim.tbl_contains(self.data.empty_rows, row) then
255+
self:append(line, self.data.col)
259256
end
260-
if padding > 0 and row > start_row and row < end_row then
261-
table.insert(virt_text, padding_text)
257+
self:append(line, margin)
258+
if row > start_row and row < end_row then
259+
self:append(line, padding, highlight)
262260
end
263-
if #virt_text > 0 then
261+
if #line > 0 then
264262
self.marks:add(false, row, self.data.col, {
265263
priority = priority,
266-
virt_text = virt_text,
264+
virt_text = line,
267265
virt_text_pos = 'inline',
268266
})
269267
end

lua/render-markdown/render/code_inline.lua

+3-3
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ end
2929
---@param row integer
3030
---@param col integer
3131
function Render:side_padding(highlight, row, col)
32-
local padding = self.code.inline_pad
33-
if padding > 0 then
32+
local line = self:append({}, self.code.inline_pad, highlight)
33+
if #line > 0 then
3434
self.marks:add(true, row, col, {
3535
priority = 0,
36-
virt_text = { self:pad(padding, highlight) },
36+
virt_text = { line },
3737
virt_text_pos = 'inline',
3838
})
3939
end

lua/render-markdown/render/dash.lua

+4-7
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,17 @@ function Render:render()
1919
width = type(width) == 'number' and self.context:resolve_offset(width, 0) or vim.o.columns
2020
local margin = self.context:resolve_offset(self.dash.left_margin, width)
2121

22-
local virt_text = {}
23-
if margin > 0 then
24-
table.insert(virt_text, self:pad(margin))
25-
end
26-
table.insert(virt_text, { self.dash.icon:rep(width), self.dash.highlight })
22+
local line = self:append({}, margin)
23+
self:append(line, self.dash.icon:rep(width), self.dash.highlight)
2724

2825
local start_row, end_row = self.node.start_row, self.node.end_row - 1
2926
self.marks:add('dash', start_row, 0, {
30-
virt_text = virt_text,
27+
virt_text = line,
3128
virt_text_pos = 'overlay',
3229
})
3330
if end_row > start_row then
3431
self.marks:add('dash', end_row, 0, {
35-
virt_text = virt_text,
32+
virt_text = line,
3633
virt_text_pos = 'overlay',
3734
})
3835
end

lua/render-markdown/render/heading.lua

+9-16
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ function Render:background(width)
213213
local win_col, padding = 0, {}
214214
if self.data.width == 'block' then
215215
win_col = width.margin + width.content + self:indent_size(self.data.level)
216-
table.insert(padding, self:pad(vim.o.columns * 2))
216+
self:append(padding, vim.o.columns * 2)
217217
end
218218
for row = self.node.start_row, self.node.end_row - 1 do
219219
self.marks:add('head_background', row, 0, {
@@ -247,12 +247,10 @@ function Render:border(width, position, icon, row)
247247
local prefix = self.heading.border_prefix and self.data.level or 0
248248
local total_width = self.data.width == 'block' and width.content or vim.o.columns
249249

250-
local line = {
251-
self:pad(width.margin),
252-
{ icon:rep(width.padding), background },
253-
{ icon:rep(prefix), foreground },
254-
{ icon:rep(total_width - width.padding - prefix), background },
255-
}
250+
local line = self:append({}, width.margin)
251+
self:append(line, icon:rep(width.padding), background)
252+
self:append(line, icon:rep(prefix), foreground)
253+
self:append(line, icon:rep(total_width - width.padding - prefix), background)
256254

257255
local virtual = self.heading.border_virtual
258256
local target_line = self.node:line(position, 1)
@@ -275,20 +273,15 @@ end
275273
---@private
276274
---@param width render.md.width.Heading
277275
function Render:left_pad(width)
278-
local virt_text = {}
279-
if width.margin > 0 then
280-
table.insert(virt_text, self:pad(width.margin))
281-
end
282-
if width.padding > 0 then
283-
table.insert(virt_text, self:pad(width.padding, self.data.background))
284-
end
285-
if #virt_text == 0 then
276+
local line = self:append({}, width.margin)
277+
self:append(line, width.padding, self.data.background)
278+
if #line == 0 then
286279
return
287280
end
288281
for row = self.node.start_row, self.node.end_row - 1 do
289282
self.marks:add(false, row, 0, {
290283
priority = 0,
291-
virt_text = virt_text,
284+
virt_text = line,
292285
virt_text_pos = 'inline',
293286
})
294287
end

lua/render-markdown/render/list_item.lua

+3-2
Original file line numberDiff line numberDiff line change
@@ -183,10 +183,11 @@ end
183183
---@param col integer
184184
---@param amount integer
185185
function Render:side_padding(row, col, amount)
186-
if amount > 0 then
186+
local line = self:append({}, amount)
187+
if #line > 0 then
187188
self.marks:add(false, row, col, {
188189
priority = 0,
189-
virt_text = { self:pad(amount) },
190+
virt_text = { line },
190191
virt_text_pos = 'inline',
191192
})
192193
end

lua/render-markdown/render/paragraph.lua

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,14 @@ function Render:render()
2323
local width = vim.fn.max(Iter.list.map(self.node:lines(), Str.width))
2424
width = math.max(width, self.paragraph.min_width)
2525
local margin = self.context:resolve_offset(self.paragraph.left_margin, width)
26-
if margin <= 0 then
26+
local line = self:append({}, margin)
27+
if #line == 0 then
2728
return
2829
end
29-
30-
local virt_text = { self:pad(margin) }
3130
for row = self.node.start_row, self.node.end_row - 1 do
3231
self.marks:add(false, row, 0, {
3332
priority = 0,
34-
virt_text = virt_text,
33+
virt_text = line,
3534
virt_text_pos = 'inline',
3635
})
3736
end

lua/render-markdown/render/shortcut.lua

+2-1
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,9 @@ function Render:checkbox(checkbox)
8181

8282
local inline = self.config.checkbox.position == 'inline'
8383
local icon, highlight = checkbox.rendered, checkbox.highlight
84+
local text = inline and icon or Str.pad_to(self.node.text, icon) .. icon
8485
local added = self.marks:add_over('check_icon', self.node, {
85-
virt_text = { { inline and icon or Str.pad_to(self.node.text, icon) .. icon, highlight } },
86+
virt_text = { { text, highlight } },
8687
virt_text_pos = 'inline',
8788
conceal = '',
8889
})

lua/render-markdown/render/table.lua

+5-3
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ function Render:shift(column, side, amount)
311311
if amount > 0 then
312312
self.marks:add(true, column.row, col, {
313313
priority = 0,
314-
virt_text = { { Str.pad(amount), self.table.filler } },
314+
virt_text = self:append({}, amount, self.table.filler),
315315
virt_text_pos = 'inline',
316316
})
317317
elseif amount < 0 then
@@ -375,9 +375,11 @@ 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:pad(spaces) } or {}
378+
local text = chars[1] .. table.concat(sections, chars[2]) .. chars[3]
379379
local highlight = above and self.table.head or self.table.row
380-
table.insert(line, { chars[1] .. table.concat(sections, chars[2]) .. chars[3], highlight })
380+
381+
local line = self:append({}, spaces)
382+
self:append(line, text, highlight)
381383
self.marks:add(false, node.start_row, node.start_col, {
382384
virt_lines = { vim.list_extend(self:indent_line(true), line) },
383385
virt_lines_above = above,

tests/indent_spec.lua

+3-8
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,14 @@ local util = require('tests.util')
77
---@param position 'above'|'below'
88
---@return render.md.MarkInfo
99
local function border(row, level, position)
10-
local foreground = util.hl(string.format('H%d', level))
1110
local background = util.hl_bg_to_fg(string.format('H%dBg', level))
1211
local icon = position == 'above' and '' or ''
13-
local line = {
14-
{ '', 'Normal' },
15-
{ '', background },
16-
{ '', foreground },
17-
{ icon:rep(vim.o.columns), background },
18-
}
1912
local virtual = row == 0 and position == 'above'
13+
local line = {}
2014
if virtual then
21-
table.insert(line, 1, { ' ', 'Normal' })
15+
table.insert(line, { ' ', 'Normal' })
2216
end
17+
table.insert(line, { icon:rep(vim.o.columns), background })
2318
---@type render.md.MarkInfo
2419
return {
2520
row = { row },

0 commit comments

Comments
 (0)