Skip to content

Commit 5ce3566

Browse files
committedJul 12, 2024
feature: Improve handling headings
# Details Previously 2 problems could occur with headings: 1. If the icon text was too long it would overwrite content 2. Concealed text was not accounted for exacerbating problem 1 To fix both of these use the width of concealed text when calculating padding. If the padding is negative (not enough space) then use an inline extmark and conceal the underlying '#'s, this will only happen when using neovim >= 0.10.0. Negative padding on older versions will skip rendering rather than overwriting text. Other change included refactors unit tests to use common mark detail creators in util, reduces the amount of boilerplate.
1 parent d398f3e commit 5ce3566

10 files changed

+411
-946
lines changed
 

Diff for: ‎doc/limitations.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
[ISSUE #35](https://github.com/MeanderingProgrammer/markdown.nvim/issues/35)
66

7-
Text that extends beyond available space will overwrite content.
7+
Text that extends beyond available space will can overwrite content.
8+
9+
This has been fixed for headings when using neovim >= `0.10.0`.
810

911
## `LaTeX` Formula Positioning
1012

Diff for: ‎lua/render-markdown/handler/markdown.lua

+31-11
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,38 @@ M.render_node = function(namespace, buf, capture, node)
4141
local background = list.clamp(heading.backgrounds, level)
4242
local foreground = list.clamp(heading.foregrounds, level)
4343

44-
-- Available width is level + 1, where level = number of `#` characters and one is
45-
-- added to account for the space after the last `#` but before the heading title
46-
local padding = level + 1 - str.width(icon)
44+
-- Available width is level + 1 - concealed, where level = number of `#` characters, one
45+
-- is added to account for the space after the last `#` but before the heading title,
46+
-- and concealed text is subtracted since that space is not usable
47+
local padding = level + 1 - ts.concealed(buf, info) - str.width(icon)
4748

48-
vim.api.nvim_buf_set_extmark(buf, namespace, info.start_row, 0, {
49-
end_row = info.end_row + 1,
50-
end_col = 0,
51-
hl_group = background,
52-
virt_text = { { str.pad(icon, padding), { foreground, background } } },
53-
virt_text_pos = 'overlay',
54-
hl_eol = true,
55-
})
49+
if padding < 0 then
50+
-- Requires inline extmarks to place when there is not enough space available
51+
if util.has_10 then
52+
vim.api.nvim_buf_set_extmark(buf, namespace, info.start_row, info.start_col, {
53+
end_row = info.end_row,
54+
end_col = info.end_col,
55+
virt_text = { { icon, { foreground, background } } },
56+
virt_text_pos = 'inline',
57+
conceal = '',
58+
})
59+
vim.api.nvim_buf_set_extmark(buf, namespace, info.start_row, 0, {
60+
end_row = info.end_row + 1,
61+
end_col = 0,
62+
hl_group = background,
63+
hl_eol = true,
64+
})
65+
end
66+
else
67+
vim.api.nvim_buf_set_extmark(buf, namespace, info.start_row, 0, {
68+
end_row = info.end_row + 1,
69+
end_col = 0,
70+
hl_group = background,
71+
virt_text = { { str.pad(icon, padding), { foreground, background } } },
72+
virt_text_pos = 'overlay',
73+
hl_eol = true,
74+
})
75+
end
5676

5777
M.render_sign(namespace, buf, info, list.cycle(heading.signs, level), foreground)
5878
elseif capture == 'dash' then

Diff for: ‎tests/box_dash_quote_spec.lua

+5-54
Original file line numberDiff line numberDiff line change
@@ -11,48 +11,9 @@ async_tests.describe('box_dash_quote.md', function()
1111
vim.list_extend(expected, util.heading(0, 1))
1212

1313
-- Checkboxes
14-
vim.list_extend(expected, {
15-
-- Unchecked, conceal list marker
16-
{
17-
row = { 2, 2 },
18-
col = { 0, 2 },
19-
conceal = '',
20-
},
21-
-- Unchecked, checkbox
22-
{
23-
row = { 2, 2 },
24-
col = { 2, 5 },
25-
virt_text = { { ' 󰄱 ', '@markup.list.unchecked' } },
26-
virt_text_pos = 'overlay',
27-
},
28-
-- Checked, conceal list marker
29-
{
30-
row = { 3, 3 },
31-
col = { 0, 2 },
32-
conceal = '',
33-
},
34-
-- Checked, checkbox
35-
{
36-
row = { 3, 3 },
37-
col = { 2, 5 },
38-
virt_text = { { ' 󰱒 ', '@markup.heading' } },
39-
virt_text_pos = 'overlay',
40-
},
41-
-- Custom todo, conceal list marker
42-
{
43-
row = { 4, 4 },
44-
col = { 0, 2 },
45-
conceal = '',
46-
},
47-
-- Custom todo, checkbox
48-
{
49-
row = { 4, 4 },
50-
col = { 2, 5 },
51-
virt_text = { { ' 󰥔 ', '@markup.raw' } },
52-
virt_text_pos = 'inline',
53-
conceal = '',
54-
},
55-
})
14+
vim.list_extend(expected, util.checkbox(2, ' 󰄱 ', '@markup.list.unchecked', false))
15+
vim.list_extend(expected, util.checkbox(3, ' 󰱒 ', '@markup.heading', false))
16+
vim.list_extend(expected, util.checkbox(4, ' 󰥔 ', '@markup.raw', true))
5617

5718
-- Line break
5819
vim.list_extend(expected, {
@@ -66,18 +27,8 @@ async_tests.describe('box_dash_quote.md', function()
6627

6728
-- Quote lines
6829
vim.list_extend(expected, {
69-
{
70-
row = { 8, 8 },
71-
col = { 0, 4 },
72-
virt_text = { { '', '@markup.quote' } },
73-
virt_text_pos = 'overlay',
74-
},
75-
{
76-
row = { 9, 9 },
77-
col = { 0, 4 },
78-
virt_text = { { '', '@markup.quote' } },
79-
virt_text_pos = 'overlay',
80-
},
30+
util.quote(8, ' %s ', '@markup.quote'),
31+
util.quote(9, ' %s ', '@markup.quote'),
8132
})
8233

8334
local actual = util.get_actual_marks()

0 commit comments

Comments
 (0)
Please sign in to comment.