Skip to content

Commit 76f7ce5

Browse files
chore(refactor): pass callback when computing extmarks to make move to async parsing easier
## Details In order to take advantage of async treesitter parsing we'll need to use a callback pattern to compute and add `extmarks` after parsing finishes. Currently (from some local testing) I'm not seeing improvements to responsiveness from this so am not making the full change to actually do this for now. However to make adopting it easier in the future I'm updating the structure of how `parse` is called to use a callback, even if it's not necessary for the time being. In order to do this the logic of displaying `extmarks` needed to be separated into its own method from the logic that sets `extmarks`. This is because in the event that we need to `parse` we need to both set and display the `extmarks` as part of the callback, and in the event we don't we just want to display the `extmarks` immediately. Since one happens in a callback and the other directly the logic can't be shared as part of the same method and needed to be moved to its own. There are technically some small changes to behavior but they should not cause any problems: - Previously we only called `on.clear` when removing marks due to a mode change. However when we `parse` and get new marks we also need to clear the buffer to remove any not needed for the current render cycle. The `on.clear` callback is now called in both of these cases. - The time between clearing old marks and showing new marks is "massively" reduced. Before we would clear, then parse, then display. Now the behavior is parse, then clear, then display. Since the parse step is the most expensive the gap is much lower, from local testing goes from 10s of milliseconds to less than 1. Neither of these is really something people can notice so no visible change.
1 parent 15869e0 commit 76f7ce5

File tree

3 files changed

+44
-27
lines changed

3 files changed

+44
-27
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Pre-release
44

5+
### Features
6+
7+
- change code.border to thin instead of hide if version < 0.11.0 [a706be7](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/a706be739257a6203524741da2da540bc190bbe2)
8+
- allow image links to use custom icons based on destination [ac3e74f](https://github.com/MeanderingProgrammer/render-markdown.nvim/commit/ac3e74ffdb0bcf7282445ac12083fb6bd44858a1)
9+
510
## 8.5.0 (2025-06-10)
611

712
### Features

lua/render-markdown/core/ui.lua

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -122,10 +122,8 @@ function Updater:run()
122122
end
123123
if not render then
124124
self:clear()
125-
M.config.on.clear({ buf = self.buf, win = self.win })
126125
else
127126
self:render()
128-
M.config.on.render({ buf = self.buf, win = self.win })
129127
end
130128
end
131129

@@ -135,20 +133,49 @@ function Updater:clear()
135133
for _, extmark in ipairs(extmarks) do
136134
extmark:hide(M.ns, self.buf)
137135
end
136+
M.config.on.clear({ buf = self.buf, win = self.win })
138137
end
139138

140139
---@private
141140
function Updater:render()
142141
if self:changed() then
143-
local initial = self.decorator:initial()
144-
self:clear()
145-
local extmarks = self:get_extmarks()
146-
self.decorator:set(extmarks)
147-
if initial then
148-
compat.fix_lsp_window(self.buf, self.win, extmarks)
149-
M.config.on.initial({ buf = self.buf, win = self.win })
150-
end
142+
self:parse(function(extmarks)
143+
if not extmarks then
144+
return
145+
end
146+
local initial = self.decorator:initial()
147+
self:clear()
148+
self.decorator:set(extmarks)
149+
if initial then
150+
compat.fix_lsp_window(self.buf, self.win, extmarks)
151+
M.config.on.initial({ buf = self.buf, win = self.win })
152+
end
153+
self:display()
154+
end)
155+
else
156+
self:display()
157+
end
158+
end
159+
160+
---@private
161+
---@param callback fun(extmarks: render.md.Extmark[]|nil)
162+
function Updater:parse(callback)
163+
local ok, parser = pcall(vim.treesitter.get_parser, self.buf)
164+
if ok and parser then
165+
-- reset buffer context
166+
local context = Context.new(self.buf, self.win, self.config, self.mode)
167+
-- make sure injections are processed
168+
context.view:parse(parser)
169+
local marks = handlers.run(context, parser)
170+
callback(iter.list.map(marks, Extmark.new))
171+
else
172+
log.buf('error', 'Fail', self.buf, 'no treesitter parser found')
173+
callback(nil)
151174
end
175+
end
176+
177+
---@private
178+
function Updater:display()
152179
local range = self:hidden()
153180
local extmarks = self.decorator:get()
154181
for _, extmark in ipairs(extmarks) do
@@ -158,22 +185,7 @@ function Updater:render()
158185
extmark:show(M.ns, self.buf)
159186
end
160187
end
161-
end
162-
163-
---@private
164-
---@return render.md.Extmark[]
165-
function Updater:get_extmarks()
166-
local ok, parser = pcall(vim.treesitter.get_parser, self.buf)
167-
if not ok or not parser then
168-
log.buf('error', 'Fail', self.buf, 'no treesitter parser found')
169-
return {}
170-
end
171-
-- reset buffer context
172-
local context = Context.new(self.buf, self.win, self.config, self.mode)
173-
-- make sure injections are processed
174-
context.view:parse(parser)
175-
local marks = handlers.run(context, parser)
176-
return iter.list.map(marks, Extmark.new)
188+
M.config.on.render({ buf = self.buf, win = self.win })
177189
end
178190

179191
---@private

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

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

0 commit comments

Comments
 (0)