Skip to content

Commit 8b4149b

Browse files
feat: support on attach callback to integrate external latex support
## Details Adds `on.attach` configurable function callback. This can be used to trigger events or other functionality that helps render a markdown document. The concrete use case has to do with triggering an external latex renderer since it does not generate any autocommands and requires the user to call it via function, keymap, or otherwise. While there is currently only a single callback point on attach this can potentially be expanded in the future to trigger other callbacks at other points in the rendering lifecycle. I do not have any concrete use cases for this now so will leave this up to feature requests.
1 parent 39a84ae commit 8b4149b

File tree

10 files changed

+145
-113
lines changed

10 files changed

+145
-113
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@
22

33
## Pre-release
44

5+
### Features
6+
7+
- margin for paragraphs [#200](https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/200)
8+
[d20d19f](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/d20d19fa54965f6eb94558c0b84fe9a942169fb4)
9+
10+
### Bug Fixes
11+
12+
- bullet point right padding priority [#199](https://github.com/MeanderingProgrammer/render-markdown.nvim/issues/199)
13+
[b02c8ef](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/b02c8ef72b10537a346556696b6e7fb354c8771f)
14+
515
## 7.3.0 (2024-10-04)
616

717
### Features

README.md

+4
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,10 @@ require('render-markdown').setup({
190190
-- Amount of empty lines below LaTeX blocks
191191
bottom_pad = 0,
192192
},
193+
on = {
194+
-- Called when plugin initially attaches to a buffer
195+
attach = function() end,
196+
},
193197
heading = {
194198
-- Turn on / off heading icon & background rendering
195199
enabled = true,

doc/limitations.md

+25-21
Original file line numberDiff line numberDiff line change
@@ -7,45 +7,49 @@
77
`LaTeX` formula evaluations are placed above text rather than overlayed.
88

99
A way around this is to use a separate plugin for `LaTeX` and disable that feature
10-
in this plugin. As examples you can use:
10+
in this plugin. Different plugins will have different setups, below are some examples:
1111

1212
[latex.nvim](https://github.com/ryleelyman/latex.nvim)
1313

1414
```lua
1515
{
16-
'ryleelyman/latex.nvim',
17-
config = function()
18-
require('latex').setup({})
19-
end,
16+
{ 'ryleelyman/latex.nvim', opts = {} },
17+
{
18+
'MeanderingProgrammer/render-markdown.nvim',
19+
dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.nvim' },
20+
opts = {
21+
latex = { enabled = false },
22+
win_options = { conceallevel = { rendered = 2 } },
23+
},
24+
},
2025
}
2126
```
2227

2328
[nabla.nvim](https://github.com/jbyuki/nabla.nvim)
2429

2530
```lua
2631
{
27-
'jbyuki/nabla.nvim',
28-
config = function()
29-
require('nabla').enable_virt({ autogen = true })
30-
end,
31-
}
32-
```
33-
34-
In both cases you'll need to disable `LaTeX` for this plugin:
35-
36-
```lua
37-
require('render-markdown').setup({
38-
latex = { enabled = false },
39-
win_options = {
40-
conceallevel = { rendered = 2 },
32+
{ 'jbyuki/nabla.nvim' },
33+
{
34+
'MeanderingProgrammer/render-markdown.nvim',
35+
dependencies = { 'nvim-treesitter/nvim-treesitter', 'echasnovski/mini.nvim' },
36+
opts = {
37+
latex = { enabled = false },
38+
win_options = { conceallevel = { rendered = 2 } },
39+
on = {
40+
attach = function()
41+
require('nabla').enable_virt({ autogen = true })
42+
end,
43+
},
44+
},
4145
},
42-
})
46+
}
4347
```
4448

4549
> [!NOTE]
4650
>
4751
> These plugins can rely on a specific `conceallevel` to work properly, which
48-
> you will need to configure in this plugin like in the example above.
52+
> you will need to configure in this plugin like in the examples above.
4953
5054
## Does Not Run in Telescope Preview
5155

doc/render-markdown.txt

+4
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,10 @@ Default Configuration ~
239239
-- Amount of empty lines below LaTeX blocks
240240
bottom_pad = 0,
241241
},
242+
on = {
243+
-- Called when plugin initially attaches to a buffer
244+
attach = function() end,
245+
},
242246
heading = {
243247
-- Turn on / off heading icon & background rendering
244248
enabled = true,

lua/render-markdown/debug/validator.lua

+39-33
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,51 @@
11
---@class render.md.debug.ValidatorSpec
22
---@field private validator render.md.debug.Validator
3-
---@field private nilable? boolean
4-
---@field private suffix string
5-
---@field private input? table<string, any>
3+
---@field private config? table<string, any>
4+
---@field private nilable boolean
5+
---@field private path string
66
---@field private opts table<string, vim.validate.Spec>
77
local Spec = {}
88
Spec.__index = Spec
99

1010
---@param validator render.md.debug.Validator
11-
---@param path string
12-
---@param input table<string, any>
11+
---@param config table<string, any>
12+
---@param nilable boolean
1313
---@param key? string|string[]
14-
---@param nilable? boolean
14+
---@param path? string
1515
---@return render.md.debug.ValidatorSpec
16-
function Spec.new(validator, path, input, key, nilable)
16+
function Spec.new(validator, config, nilable, key, path)
1717
local self = setmetatable({}, Spec)
1818
self.validator = validator
19+
self.config = config
1920
self.nilable = nilable
20-
self.suffix = path
21-
self.input = input
21+
self.path = path or ''
2222
self.opts = {}
2323
if key ~= nil then
2424
key = type(key) == 'table' and key or { key }
25-
self.suffix = self.suffix .. '.' .. table.concat(key, '.')
26-
self.input = vim.tbl_get(self.input, unpack(key))
27-
assert(self.input ~= nil or self.nilable == true)
25+
self.path = self.path .. '.' .. table.concat(key, '.')
26+
self.config = vim.tbl_get(self.config, unpack(key))
27+
assert(self.config ~= nil or self.nilable)
2828
end
2929
return self
3030
end
3131

3232
---@return string
33-
function Spec:get_suffix()
34-
return self.suffix
33+
function Spec:get_path()
34+
return self.path
3535
end
3636

3737
---@return table<string, any>
38-
function Spec:get_input()
39-
return self.input
38+
function Spec:get_config()
39+
return self.config
4040
end
4141

42+
---@param nilable boolean
4243
---@param f fun(spec: render.md.debug.ValidatorSpec)
43-
---@param nilable? boolean
44-
function Spec:for_each(f, nilable)
45-
for name in pairs(self.input or {}) do
46-
f(Spec.new(self.validator, self.suffix, self.input, name, nilable))
44+
function Spec:for_each(nilable, f)
45+
for name in pairs(self.config or {}) do
46+
local spec = Spec.new(self.validator, self.config, nilable, name, self.path)
47+
f(spec)
48+
spec:check()
4749
end
4850
end
4951

@@ -123,7 +125,7 @@ function Spec:handle_types(input_types)
123125
else
124126
types = input_types
125127
end
126-
if self.nilable then
128+
if self.nilable and not vim.tbl_contains(types, 'nil') then
127129
table.insert(types, 'nil')
128130
end
129131
return types, #types == 0 and '' or (' or type ' .. vim.inspect(types))
@@ -135,20 +137,24 @@ end
135137
---@param message string?
136138
---@return render.md.debug.ValidatorSpec
137139
function Spec:add(keys, logic, message)
138-
if self.input ~= nil then
140+
if self.config ~= nil then
139141
keys = type(keys) == 'table' and keys or { keys }
140142
for _, key in ipairs(keys) do
141143
---@diagnostic disable-next-line: assign-type-mismatch
142-
self.opts[key] = { self.input[key], logic, message or self.nilable }
144+
self.opts[key] = { self.config[key], logic, message or self.nilable }
143145
end
144146
end
145147
return self
146148
end
147149

148150
function Spec:check()
149-
if self.input ~= nil then
150-
self.validator:check(self.suffix, self.input, self.opts)
151+
if self.config == nil then
152+
return
151153
end
154+
if vim.tbl_count(self.opts) == 0 then
155+
return
156+
end
157+
self.validator:check(self.path, self.config, self.opts)
152158
end
153159

154160
---@class render.md.debug.Validator
@@ -165,25 +171,25 @@ function Validator.new()
165171
return self
166172
end
167173

168-
---@param path string
169-
---@param input table<string, any>
174+
---@param config table<string, any>
175+
---@param nilable boolean
170176
---@param key? string|string[]
171-
---@param nilable? boolean
177+
---@param path? string
172178
---@return render.md.debug.ValidatorSpec
173-
function Validator:spec(path, input, key, nilable)
174-
return Spec.new(self, path, input, key, nilable)
179+
function Validator:spec(config, nilable, key, path)
180+
return Spec.new(self, config, nilable, key, path)
175181
end
176182

177183
---@param suffix string
178-
---@param input table<string, any>
184+
---@param config table<string, any>
179185
---@param opts table<string, vim.validate.Spec>
180-
function Validator:check(suffix, input, opts)
186+
function Validator:check(suffix, config, opts)
181187
local path = self.prefix .. suffix
182188
local ok, err = pcall(vim.validate, opts)
183189
if not ok then
184190
table.insert(self.errors, path .. '.' .. err)
185191
end
186-
for key, _ in pairs(input) do
192+
for key, _ in pairs(config) do
187193
if opts[key] == nil then
188194
table.insert(self.errors, string.format('%s.%s: is not a valid key', path, key))
189195
end

lua/render-markdown/health.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ local state = require('render-markdown.state')
44
local M = {}
55

66
---@private
7-
M.version = '7.3.2'
7+
M.version = '7.3.3'
88

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

lua/render-markdown/init.lua

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ local M = {}
1111
---@field public extends? boolean
1212
---@field public parse fun(root: TSNode, buf: integer): render.md.Mark[]
1313

14+
---@class (exact) render.md.UserCallback
15+
---@field public attach? fun(buf: integer)
16+
1417
---@class (exact) render.md.UserLatex
1518
---@field public enabled? boolean
1619
---@field public converter? string
@@ -204,6 +207,7 @@ local M = {}
204207
---@field public file_types? string[]
205208
---@field public injections? table<string, render.md.UserInjection>
206209
---@field public latex? render.md.UserLatex
210+
---@field public on? render.md.UserCallback
207211
---@field public overrides? render.md.UserConfigOverrides
208212
---@field public custom_handlers? table<string, render.md.Handler>
209213

@@ -272,6 +276,10 @@ M.default_config = {
272276
-- Amount of empty lines below LaTeX blocks
273277
bottom_pad = 0,
274278
},
279+
on = {
280+
-- Called when plugin initially attaches to a buffer
281+
attach = function() end,
282+
},
275283
heading = {
276284
-- Turn on / off heading icon & background rendering
277285
enabled = true,

lua/render-markdown/manager.lua

+3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,10 @@ function M.attach(buf)
5151
if not M.should_attach(buf) then
5252
return
5353
end
54+
5455
local config = state.get(buf)
56+
state.on.attach(buf)
57+
5558
local events = { 'BufWinEnter', 'BufLeave', 'CursorHold', 'CursorMoved', 'WinScrolled' }
5659
local change_events = { 'DiffUpdated', 'ModeChanged', 'TextChanged' }
5760
if config:render('i') then

0 commit comments

Comments
 (0)