Skip to content

Commit e6695b4

Browse files
feat: Add support for wiki links
## Details Another version of a shortcut link, when enclosed in double square brackets. Support for using alias instead of direct link. Feature comes from obsidian: https://help.obsidian.md/Linking+notes+and+files/Internal+links
1 parent c7a2055 commit e6695b4

File tree

9 files changed

+152
-58
lines changed

9 files changed

+152
-58
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
### Features
2323

24+
- Performance only parse & render visible range [c7a2055](https://github.com/MeanderingProgrammer/markdown.nvim/commit/c7a20552b83c2abad92ac5e52feb7fe3b929f0a7)
2425
- Support full buftype options [9a8a2e5](https://github.com/MeanderingProgrammer/markdown.nvim/commit/9a8a2e5bd204931646f1559235c7c4a7680ecbcd)
2526
- Inline heading position [#107](https://github.com/MeanderingProgrammer/markdown.nvim/issues/107)
2627
[345596b](https://github.com/MeanderingProgrammer/markdown.nvim/commit/345596bb6ef2b0c0a145c59906c2e84dbddfbbd4)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ require('render-markdown').setup({
167167
inline_query = [[
168168
(code_span) @code
169169
170-
(shortcut_link) @callout
170+
(shortcut_link) @shortcut
171171
172172
[(inline_link) (full_reference_link) (image)] @link
173173
]],

doc/render-markdown.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For 0.10.0 Last change: 2024 August 01
1+
*render-markdown.txt* For 0.10.0 Last change: 2024 August 02
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*
@@ -200,7 +200,7 @@ Full Default Configuration ~
200200
inline_query = [[
201201
(code_span) @code
202202

203-
(shortcut_link) @callout
203+
(shortcut_link) @shortcut
204204

205205
[(inline_link) (full_reference_link) (image)] @link
206206
]],

lua/render-markdown/handler/markdown_inline.lua

Lines changed: 101 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ function M.parse(root, buf)
2121
logger.debug_node_info(capture, info)
2222
if capture == 'code' then
2323
list.add_mark(marks, M.code(config, info))
24-
elseif capture == 'callout' then
25-
list.add_mark(marks, M.callout(config, buf, info))
24+
elseif capture == 'shortcut' then
25+
list.add_mark(marks, M.shortcut(config, buf, info))
2626
elseif capture == 'link' then
2727
list.add_mark(marks, M.link(config, buf, info))
2828
else
@@ -62,11 +62,32 @@ end
6262
---@param buf integer
6363
---@param info render.md.NodeInfo
6464
---@return render.md.Mark?
65-
function M.callout(config, buf, info)
65+
function M.shortcut(config, buf, info)
66+
local callout = component.callout(config, info.text, 'exact')
67+
if callout ~= nil then
68+
return M.callout(config, buf, info, callout)
69+
end
70+
local checkbox = component.checkbox(config, info.text, 'exact')
71+
if checkbox ~= nil then
72+
return M.checkbox(config, info, checkbox)
73+
end
74+
local line = vim.api.nvim_buf_get_lines(buf, info.start_row, info.start_row + 1, true)[1]
75+
if line:find('[' .. info.text .. ']', 1, true) ~= nil then
76+
return M.wiki_link(config, info)
77+
end
78+
return nil
79+
end
80+
81+
---@private
82+
---@param config render.md.BufferConfig
83+
---@param buf integer
84+
---@param info render.md.NodeInfo
85+
---@param callout render.md.CustomComponent
86+
---@return render.md.Mark?
87+
function M.callout(config, buf, info, callout)
6688
---Support for overriding title: https://help.obsidian.md/Editing+and+formatting/Callouts#Change+the+title
67-
---@param callout render.md.CustomComponent
6889
---@return string, string?
69-
local function custom_title(callout)
90+
local function custom_title()
7091
local content = ts.parent(buf, info, 'inline')
7192
if content ~= nil then
7293
local line = str.split(content.text, '\n')[1]
@@ -79,51 +100,81 @@ function M.callout(config, buf, info)
79100
return callout.rendered, nil
80101
end
81102

82-
local callout = component.callout(config, info.text, 'exact')
83-
if callout ~= nil then
84-
if not config.quote.enabled then
85-
return nil
86-
end
87-
local text, conceal = custom_title(callout)
88-
---@type render.md.Mark
89-
return {
90-
conceal = true,
91-
start_row = info.start_row,
92-
start_col = info.start_col,
93-
opts = {
94-
end_row = info.end_row,
95-
end_col = info.end_col,
96-
virt_text = { { text, callout.highlight } },
97-
virt_text_pos = 'overlay',
98-
conceal = conceal,
99-
},
100-
}
101-
else
102-
if not config.checkbox.enabled then
103-
return nil
104-
end
105-
-- Requires inline extmarks
106-
if not util.has_10 then
107-
return nil
108-
end
109-
local checkbox = component.checkbox(config, info.text, 'exact')
110-
if checkbox == nil then
111-
return nil
112-
end
113-
---@type render.md.Mark
114-
return {
115-
conceal = true,
116-
start_row = info.start_row,
117-
start_col = info.start_col,
118-
opts = {
119-
end_row = info.end_row,
120-
end_col = info.end_col,
121-
virt_text = { { str.pad_to(info.text, checkbox.rendered), checkbox.highlight } },
122-
virt_text_pos = 'inline',
123-
conceal = '',
124-
},
125-
}
103+
if not config.quote.enabled then
104+
return nil
126105
end
106+
local text, conceal = custom_title()
107+
---@type render.md.Mark
108+
return {
109+
conceal = true,
110+
start_row = info.start_row,
111+
start_col = info.start_col,
112+
opts = {
113+
end_row = info.end_row,
114+
end_col = info.end_col,
115+
virt_text = { { text, callout.highlight } },
116+
virt_text_pos = 'overlay',
117+
conceal = conceal,
118+
},
119+
}
120+
end
121+
122+
---@private
123+
---@param config render.md.BufferConfig
124+
---@param info render.md.NodeInfo
125+
---@param checkbox render.md.CustomComponent
126+
---@return render.md.Mark?
127+
function M.checkbox(config, info, checkbox)
128+
if not config.checkbox.enabled then
129+
return nil
130+
end
131+
-- Requires inline extmarks
132+
if not util.has_10 then
133+
return nil
134+
end
135+
---@type render.md.Mark
136+
return {
137+
conceal = true,
138+
start_row = info.start_row,
139+
start_col = info.start_col,
140+
opts = {
141+
end_row = info.end_row,
142+
end_col = info.end_col,
143+
virt_text = { { str.pad_to(info.text, checkbox.rendered), checkbox.highlight } },
144+
virt_text_pos = 'inline',
145+
conceal = '',
146+
},
147+
}
148+
end
149+
150+
---@private
151+
---@param config render.md.BufferConfig
152+
---@param info render.md.NodeInfo
153+
---@return render.md.Mark?
154+
function M.wiki_link(config, info)
155+
local link = config.link
156+
if not link.enabled then
157+
return nil
158+
end
159+
-- Requires inline extmarks
160+
if not util.has_10 then
161+
return nil
162+
end
163+
local text = info.text:sub(2, -2)
164+
local elements = str.split(text, '|')
165+
---@type render.md.Mark
166+
return {
167+
conceal = true,
168+
start_row = info.start_row,
169+
start_col = info.start_col - 1,
170+
opts = {
171+
end_row = info.end_row,
172+
end_col = info.end_col + 1,
173+
virt_text = { { link.hyperlink .. elements[#elements], link.highlight } },
174+
virt_text_pos = 'inline',
175+
conceal = '',
176+
},
177+
}
127178
end
128179

129180
---@private
@@ -158,7 +209,7 @@ function M.link(config, buf, info)
158209
opts = {
159210
end_row = info.end_row,
160211
end_col = info.end_col,
161-
virt_text = { { icon, config.link.highlight } },
212+
virt_text = { { icon, link.highlight } },
162213
virt_text_pos = 'inline',
163214
},
164215
}

lua/render-markdown/init.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ M.default_config = {
184184
inline_query = [[
185185
(code_span) @code
186186
187-
(shortcut_link) @callout
187+
(shortcut_link) @shortcut
188188
189189
[(inline_link) (full_reference_link) (image)] @link
190190
]],

lua/render-markdown/manager.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function M.setup()
2828
for _, win in ipairs(vim.v.event.windows) do
2929
local buf = util.win_to_buf(win)
3030
if vim.tbl_contains(buffers, buf) then
31-
ui.debcoune_update(buf)
31+
ui.debounce_update(buf)
3232
end
3333
end
3434
end,
@@ -41,7 +41,7 @@ function M.set_all(enabled)
4141
M.attach(vim.api.nvim_get_current_buf())
4242
state.enabled = enabled
4343
for _, buf in ipairs(buffers) do
44-
ui.debcoune_update(buf)
44+
ui.debounce_update(buf)
4545
end
4646
end
4747

@@ -73,7 +73,7 @@ function M.attach(buf)
7373
group = M.group,
7474
buffer = buf,
7575
callback = function()
76-
ui.debcoune_update(buf)
76+
ui.debounce_update(buf)
7777
end,
7878
})
7979
end

lua/render-markdown/ui.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function M.clear(buf)
3434
end
3535

3636
---@param buf integer
37-
function M.debcoune_update(buf)
37+
function M.debounce_update(buf)
3838
local buf_state = cache[buf] or buffer_state.new(buf)
3939
cache[buf] = buf_state
4040
buf_state:debounce(state.get_config(buf).debounce, M.update)

tests/ad_hoc_spec.lua

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---@module 'luassert'
2+
3+
local util = require('tests.util')
4+
5+
---@param row integer
6+
---@param start_col integer
7+
---@param end_col integer
8+
---@param text string
9+
---@return render.md.MarkInfo
10+
local function wiki_link(row, start_col, end_col, text)
11+
---@type render.md.MarkInfo
12+
return {
13+
row = { row, row },
14+
col = { start_col, end_col },
15+
virt_text = { { '󰌹 ' .. text, util.hl('Link') } },
16+
virt_text_pos = 'inline',
17+
conceal = '',
18+
}
19+
end
20+
21+
describe('ad_hoc.md', function()
22+
it('default', function()
23+
util.setup('tests/data/ad_hoc.md')
24+
25+
local expected = {}
26+
vim.list_extend(expected, util.heading(0, 1))
27+
vim.list_extend(expected, {
28+
wiki_link(4, 0, 13, 'Basic One'),
29+
wiki_link(6, 0, 23, 'With Alias'),
30+
})
31+
32+
local actual = util.get_actual_marks()
33+
util.marks_are_equal(expected, actual)
34+
end)
35+
end)

tests/data/ad_hoc.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Heading
2+
3+
[Normal Shortcut]
4+
5+
[[Basic One]] Then normal text
6+
7+
[[Nickname|With Alias]] Something important

0 commit comments

Comments
 (0)