Skip to content

Commit 059f503

Browse files
fix: lsp hover doc for neovim < 0.11.0
## Details Follow up to the fix for 0.11.0: b57d51d That change ended up causing the same problem that existed for 0.11.0 for older versions of neovim, i.e. not rendering on the initial load. This is due to when the LSP window is created. On the `initial` run the first call would use a non-final floating window. The final one gets created later. Due to the debounce the next call with the correct window was skipped. To fix this add a check that the buffer is not empty before triggering the update. This should work for all versions and skipping empty buffers should always be valid. Minor refactor: rename `BufferState` -> `Buffer`.
1 parent 03e6b3f commit 059f503

File tree

8 files changed

+136
-115
lines changed

8 files changed

+136
-115
lines changed

README.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -176,18 +176,18 @@ Some of the more useful fields are discussed further down.
176176
require('render-markdown').setup({
177177
-- Whether markdown should be rendered by default.
178178
enabled = true,
179-
-- Vim modes that will show a rendered view of the markdown file, :h mode(), for
180-
-- all enabled components. Individual components can be enabled for other modes.
181-
-- Remaining modes will be unaffected by this plugin.
179+
-- Vim modes that will show a rendered view of the markdown file, :h mode(), for all enabled
180+
-- components. Individual components can be enabled for other modes. Remaining modes will be
181+
-- unaffected by this plugin.
182182
render_modes = { 'n', 'c', 't' },
183183
-- Maximum file size (in MB) that this plugin will attempt to render.
184184
-- Any file larger than this will effectively be ignored.
185185
max_file_size = 10.0,
186186
-- Milliseconds that must pass before updating marks, updates occur.
187187
-- within the context of the visible window, not the entire buffer.
188188
debounce = 100,
189-
-- Pre configured settings that will attempt to mimic various target
190-
-- user experiences. Any user provided settings will take precedence.
189+
-- Pre configured settings that will attempt to mimic various target user experiences.
190+
-- Any user provided settings will take precedence.
191191
-- | obsidian | mimic Obsidian UI |
192192
-- | lazy | will attempt to stay up to date with LazyVim configuration |
193193
-- | none | does nothing |
@@ -221,7 +221,7 @@ require('render-markdown').setup({
221221
enabled = true,
222222
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
223223
-- booleans to fix the behavior or string lists representing modes where anti conceal
224-
-- behavior will be ignored. Possible keys are:
224+
-- behavior will be ignored. Valid values are:
225225
-- head_icon, head_background, head_border, code_language, code_background, code_border
226226
-- dash, bullet, check_icon, check_scope, quote, table_border, callout, link, sign
227227
ignore = {
@@ -238,7 +238,7 @@ require('render-markdown').setup({
238238
highlight = 'Normal',
239239
},
240240
latex = {
241-
-- Whether latex should be rendered, mainly used for health check
241+
-- Turn on / off latex rendering.
242242
enabled = true,
243243
-- Additional modes to render latex.
244244
render_modes = false,
@@ -505,10 +505,10 @@ require('render-markdown').setup({
505505
-- Define custom checkbox states, more involved, not part of the markdown grammar.
506506
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
507507
-- The key is for healthcheck and to allow users to change its values, value type below.
508-
-- | raw | matched against the raw text of a 'shortcut_link' |
509-
-- | rendered | replaces the 'raw' value when rendering |
510-
-- | highlight | highlight for the 'rendered' icon |
511-
-- | scope_highlight | highlight for item associated with custom checkbox |
508+
-- | raw | matched against the raw text of a 'shortcut_link' |
509+
-- | rendered | replaces the 'raw' value when rendering |
510+
-- | highlight | highlight for the 'rendered' icon |
511+
-- | scope_highlight | optional highlight for item associated with custom checkbox |
512512
custom = {
513513
todo = { raw = '[-]', rendered = '󰥔 ', highlight = 'RenderMarkdownTodo', scope_highlight = nil },
514514
},
@@ -1095,10 +1095,10 @@ require('render-markdown').setup({
10951095
-- Define custom checkbox states, more involved, not part of the markdown grammar.
10961096
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
10971097
-- The key is for healthcheck and to allow users to change its values, value type below.
1098-
-- | raw | matched against the raw text of a 'shortcut_link' |
1099-
-- | rendered | replaces the 'raw' value when rendering |
1100-
-- | highlight | highlight for the 'rendered' icon |
1101-
-- | scope_highlight | highlight for item associated with custom checkbox |
1098+
-- | raw | matched against the raw text of a 'shortcut_link' |
1099+
-- | rendered | replaces the 'raw' value when rendering |
1100+
-- | highlight | highlight for the 'rendered' icon |
1101+
-- | scope_highlight | optional highlight for item associated with custom checkbox |
11021102
custom = {
11031103
todo = { raw = '[-]', rendered = '󰥔 ', highlight = 'RenderMarkdownTodo', scope_highlight = nil },
11041104
},

doc/render-markdown.txt

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -237,18 +237,18 @@ Default Configuration ~
237237
require('render-markdown').setup({
238238
-- Whether markdown should be rendered by default.
239239
enabled = true,
240-
-- Vim modes that will show a rendered view of the markdown file, :h mode(), for
241-
-- all enabled components. Individual components can be enabled for other modes.
242-
-- Remaining modes will be unaffected by this plugin.
240+
-- Vim modes that will show a rendered view of the markdown file, :h mode(), for all enabled
241+
-- components. Individual components can be enabled for other modes. Remaining modes will be
242+
-- unaffected by this plugin.
243243
render_modes = { 'n', 'c', 't' },
244244
-- Maximum file size (in MB) that this plugin will attempt to render.
245245
-- Any file larger than this will effectively be ignored.
246246
max_file_size = 10.0,
247247
-- Milliseconds that must pass before updating marks, updates occur.
248248
-- within the context of the visible window, not the entire buffer.
249249
debounce = 100,
250-
-- Pre configured settings that will attempt to mimic various target
251-
-- user experiences. Any user provided settings will take precedence.
250+
-- Pre configured settings that will attempt to mimic various target user experiences.
251+
-- Any user provided settings will take precedence.
252252
-- | obsidian | mimic Obsidian UI |
253253
-- | lazy | will attempt to stay up to date with LazyVim configuration |
254254
-- | none | does nothing |
@@ -282,7 +282,7 @@ Default Configuration ~
282282
enabled = true,
283283
-- Which elements to always show, ignoring anti conceal behavior. Values can either be
284284
-- booleans to fix the behavior or string lists representing modes where anti conceal
285-
-- behavior will be ignored. Possible keys are:
285+
-- behavior will be ignored. Valid values are:
286286
-- head_icon, head_background, head_border, code_language, code_background, code_border
287287
-- dash, bullet, check_icon, check_scope, quote, table_border, callout, link, sign
288288
ignore = {
@@ -299,7 +299,7 @@ Default Configuration ~
299299
highlight = 'Normal',
300300
},
301301
latex = {
302-
-- Whether latex should be rendered, mainly used for health check
302+
-- Turn on / off latex rendering.
303303
enabled = true,
304304
-- Additional modes to render latex.
305305
render_modes = false,
@@ -566,10 +566,10 @@ Default Configuration ~
566566
-- Define custom checkbox states, more involved, not part of the markdown grammar.
567567
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
568568
-- The key is for healthcheck and to allow users to change its values, value type below.
569-
-- | raw | matched against the raw text of a 'shortcut_link' |
570-
-- | rendered | replaces the 'raw' value when rendering |
571-
-- | highlight | highlight for the 'rendered' icon |
572-
-- | scope_highlight | highlight for item associated with custom checkbox |
569+
-- | raw | matched against the raw text of a 'shortcut_link' |
570+
-- | rendered | replaces the 'raw' value when rendering |
571+
-- | highlight | highlight for the 'rendered' icon |
572+
-- | scope_highlight | optional highlight for item associated with custom checkbox |
573573
custom = {
574574
todo = { raw = '[-]', rendered = '󰥔 ', highlight = 'RenderMarkdownTodo', scope_highlight = nil },
575575
},
@@ -1144,10 +1144,10 @@ Checkbox Configuration ~
11441144
-- Define custom checkbox states, more involved, not part of the markdown grammar.
11451145
-- As a result this requires neovim >= 0.10.0 since it relies on 'inline' extmarks.
11461146
-- The key is for healthcheck and to allow users to change its values, value type below.
1147-
-- | raw | matched against the raw text of a 'shortcut_link' |
1148-
-- | rendered | replaces the 'raw' value when rendering |
1149-
-- | highlight | highlight for the 'rendered' icon |
1150-
-- | scope_highlight | highlight for item associated with custom checkbox |
1147+
-- | raw | matched against the raw text of a 'shortcut_link' |
1148+
-- | rendered | replaces the 'raw' value when rendering |
1149+
-- | highlight | highlight for the 'rendered' icon |
1150+
-- | scope_highlight | optional highlight for item associated with custom checkbox |
11511151
custom = {
11521152
todo = { raw = '[-]', rendered = '󰥔 ', highlight = 'RenderMarkdownTodo', scope_highlight = nil },
11531153
},

lua/render-markdown/core/buffer.lua

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---@class render.md.Buffer
2+
---@field private buf integer
3+
---@field private empty boolean
4+
---@field private timer uv_timer_t
5+
---@field private running boolean
6+
---@field private marks? render.md.Extmark[]
7+
local Buffer = {}
8+
Buffer.__index = Buffer
9+
10+
---@param buf integer
11+
---@return render.md.Buffer
12+
function Buffer.new(buf)
13+
local self = setmetatable({}, Buffer)
14+
self.buf = buf
15+
self.empty = true
16+
self.timer = (vim.uv or vim.loop).new_timer()
17+
self.running = false
18+
self.marks = nil
19+
return self
20+
end
21+
22+
---@return boolean
23+
function Buffer:is_empty()
24+
if self.empty then
25+
if vim.api.nvim_buf_line_count(self.buf) > 1 then
26+
self.empty = false
27+
else
28+
local line = vim.api.nvim_buf_get_lines(self.buf, 0, -1, false)[1]
29+
self.empty = line == nil or line == ''
30+
end
31+
end
32+
return self.empty
33+
end
34+
35+
---@param ms integer
36+
---@param callback fun()
37+
function Buffer:debounce(ms, callback)
38+
self.timer:start(ms, 0, function()
39+
self.running = false
40+
end)
41+
if not self.running then
42+
self.running = true
43+
vim.schedule(callback)
44+
end
45+
end
46+
47+
---@return boolean
48+
function Buffer:has_marks()
49+
return self.marks ~= nil
50+
end
51+
52+
---@return render.md.Extmark[]
53+
function Buffer:get_marks()
54+
return self.marks or {}
55+
end
56+
57+
---@param marks? render.md.Extmark[]
58+
function Buffer:set_marks(marks)
59+
self.marks = marks
60+
end
61+
62+
return Buffer

lua/render-markdown/core/buffer_state.lua

Lines changed: 0 additions & 44 deletions
This file was deleted.

lua/render-markdown/core/ui.lua

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
local BufferState = require('render-markdown.core.buffer_state')
1+
local Buffer = require('render-markdown.core.buffer')
22
local Context = require('render-markdown.core.context')
33
local Extmark = require('render-markdown.core.extmark')
44
local Iter = require('render-markdown.lib.iter')
@@ -15,20 +15,20 @@ local builtin_handlers = {
1515
}
1616

1717
---@class render.md.cache.Ui
18-
---@field states table<integer, render.md.BufferState>
18+
---@field states table<integer, render.md.Buffer>
1919
local Cache = {
2020
states = {},
2121
}
2222

2323
---@param buf integer
24-
---@return render.md.BufferState
24+
---@return render.md.Buffer
2525
function Cache.get(buf)
26-
local buffer_state = Cache.states[buf]
27-
if buffer_state == nil then
28-
buffer_state = BufferState.new()
29-
Cache.states[buf] = buffer_state
26+
local buffer = Cache.states[buf]
27+
if buffer == nil then
28+
buffer = Buffer.new(buf)
29+
Cache.states[buf] = buffer
3030
end
31-
return buffer_state
31+
return buffer
3232
end
3333

3434
---@class render.md.Ui
@@ -37,8 +37,8 @@ local M = {}
3737
M.ns = vim.api.nvim_create_namespace('render-markdown.nvim')
3838

3939
function M.invalidate_cache()
40-
for buf, buffer_state in pairs(Cache.states) do
41-
M.clear(buf, buffer_state)
40+
for buf, buffer in pairs(Cache.states) do
41+
M.clear(buf, buffer)
4242
end
4343
Cache.states = {}
4444
end
@@ -47,13 +47,13 @@ end
4747
---@param win integer
4848
---@return integer, render.md.Mark[]
4949
function M.get_row_marks(buf, win)
50-
local config, buffer_state = state.get(buf), Cache.get(buf)
50+
local config, buffer = state.get(buf), Cache.get(buf)
5151
local mode, row = util.mode(), util.row(buf, win)
5252
local hidden = config:hidden(mode, row)
5353
assert(row ~= nil and hidden ~= nil, 'Row & range must be known to get marks')
5454

5555
local marks = {}
56-
for _, extmark in ipairs(buffer_state:get_marks()) do
56+
for _, extmark in ipairs(buffer:get_marks()) do
5757
if extmark:inside(hidden) then
5858
table.insert(marks, extmark:get())
5959
end
@@ -63,10 +63,10 @@ end
6363

6464
---@private
6565
---@param buf integer
66-
---@param buffer_state render.md.BufferState
67-
function M.clear(buf, buffer_state)
66+
---@param buffer render.md.Buffer
67+
function M.clear(buf, buffer)
6868
vim.api.nvim_buf_clear_namespace(buf, M.ns, 0, -1)
69-
buffer_state:set_marks(nil)
69+
buffer:set_marks(nil)
7070
end
7171

7272
---Used directly by fzf-lua: https://github.com/ibhagwan/fzf-lua/blob/main/lua/fzf-lua/previewer/builtin.lua
@@ -76,12 +76,15 @@ end
7676
---@param change boolean
7777
function M.update(buf, win, event, change)
7878
log.buf('info', 'update', buf, string.format('event %s', event), string.format('change %s', change))
79-
if not util.valid(buf, win) then
79+
if util.invalid(buf, win) then
8080
return
8181
end
8282

8383
local parse = M.parse(buf, win, change)
84-
local config, buffer_state = state.get(buf), Cache.get(buf)
84+
local config, buffer = state.get(buf), Cache.get(buf)
85+
if buffer:is_empty() then
86+
return
87+
end
8588

8689
local update = function()
8790
M.run_update(buf, win, change)
@@ -91,7 +94,7 @@ function M.update(buf, win, event, change)
9194
end
9295

9396
if parse and config.debounce > 0 then
94-
buffer_state:debounce(config.debounce, update)
97+
buffer:debounce(config.debounce, update)
9598
else
9699
vim.schedule(update)
97100
end
@@ -112,12 +115,12 @@ end
112115
---@param win integer
113116
---@param change boolean
114117
function M.run_update(buf, win, change)
115-
if not util.valid(buf, win) then
118+
if util.invalid(buf, win) then
116119
return
117120
end
118121

119122
local parse = M.parse(buf, win, change)
120-
local config, buffer_state = state.get(buf), Cache.get(buf)
123+
local config, buffer = state.get(buf), Cache.get(buf)
121124
local mode, row = util.mode(), util.row(buf, win)
122125
local next_state = M.next_state(config, win, mode)
123126

@@ -129,17 +132,17 @@ function M.run_update(buf, win, change)
129132
end
130133

131134
if next_state == 'rendered' then
132-
if not buffer_state:has_marks() or parse then
133-
M.clear(buf, buffer_state)
134-
buffer_state:set_marks(M.parse_buffer({
135+
if not buffer:has_marks() or parse then
136+
M.clear(buf, buffer)
137+
buffer:set_marks(M.parse_buffer({
135138
buf = buf,
136139
win = win,
137140
mode = mode,
138141
top_level_mode = util.in_modes(config.render_modes, mode),
139142
}))
140143
end
141144
local hidden = config:hidden(mode, row)
142-
local extmarks = buffer_state:get_marks()
145+
local extmarks = buffer:get_marks()
143146
for _, extmark in ipairs(extmarks) do
144147
if extmark:get().conceal and extmark:inside(hidden) then
145148
extmark:hide(M.ns, buf)
@@ -149,7 +152,7 @@ function M.run_update(buf, win, change)
149152
end
150153
state.on.render({ buf = buf })
151154
else
152-
M.clear(buf, buffer_state)
155+
M.clear(buf, buffer)
153156
state.on.clear({ buf = buf })
154157
end
155158
end

0 commit comments

Comments
 (0)