Skip to content

Commit 4f05de7

Browse files
feat: include hightlight query files in checkhealth
## Details Hightlight query files are now provided in output of the checkhealth command, only really helpful to improve debugging issues for users. Common issues around content not being concealed as expected arise from users or plugins overwriting rather than extending.
1 parent a1b0988 commit 4f05de7

File tree

4 files changed

+87
-64
lines changed

4 files changed

+87
-64
lines changed

doc/render-markdown.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*render-markdown.txt* For NVIM v0.11.1 Last change: 2025 May 12
1+
*render-markdown.txt* For NVIM v0.11.1 Last change: 2025 May 19
22

33
==============================================================================
44
Table of Contents *render-markdown-table-of-contents*

lua/render-markdown/health.lua

Lines changed: 63 additions & 47 deletions
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.4.1'
8+
M.version = '8.4.2'
99

1010
function M.check()
1111
M.start('version')
@@ -22,15 +22,21 @@ function M.check()
2222
end
2323

2424
local config = state.get(0)
25-
local latex, latex_advice = config.latex, M.disable_advice('latex')
26-
local html, html_advice = config.html, M.disable_advice('html')
25+
local latex = config.latex
26+
local html = config.html
2727

2828
M.start('treesitter')
29-
M.check_parser('markdown', true)
30-
M.check_parser('markdown_inline', true)
31-
M.check_parser('latex', latex.enabled, latex_advice)
32-
M.check_parser('html', html.enabled, html_advice)
33-
M.check_highlight('markdown')
29+
M.parser('markdown', true)
30+
M.highlights('markdown')
31+
M.highlighter('markdown')
32+
M.parser('markdown_inline', true)
33+
M.highlights('markdown_inline')
34+
if latex.enabled then
35+
M.parser('latex', false)
36+
end
37+
if html.enabled then
38+
M.parser('html', false)
39+
end
3440

3541
M.start('icons')
3642
local provider = Icons.name()
@@ -41,12 +47,14 @@ function M.check()
4147
end
4248

4349
M.start('executables')
44-
M.check_executable(latex.converter, latex.enabled, latex_advice)
50+
if latex.enabled then
51+
M.executable(latex.converter, M.disable('latex'))
52+
end
4553

4654
M.start('conflicts')
47-
M.check_plugin('headlines')
48-
M.check_plugin('markview')
49-
M.check_plugin('obsidian', function(obsidian)
55+
M.plugin('headlines')
56+
M.plugin('markview')
57+
M.plugin('obsidian', function(obsidian)
5058
if obsidian.get_client().opts.ui.enable == false then
5159
return nil
5260
else
@@ -77,69 +85,66 @@ function M.neovim(min, rec)
7785
end
7886
end
7987

80-
---@private
81-
---@param language string
82-
---@return string[]
83-
function M.disable_advice(language)
84-
local setup = "require('render-markdown').setup"
85-
return {
86-
('disable %s support to avoid this warning'):format(language),
87-
('%s({ %s = { enabled = false } })'):format(setup, language),
88-
}
89-
end
90-
9188
---@private
9289
---@param language string
9390
---@param required boolean
94-
---@param advice? string[]
95-
function M.check_parser(language, required, advice)
96-
local has_parser = pcall(vim.treesitter.get_parser, 0, language)
97-
if has_parser then
91+
function M.parser(language, required)
92+
local ok = pcall(vim.treesitter.get_parser, 0, language)
93+
if ok then
9894
vim.health.ok(language .. ': parser installed')
9995
else
10096
local message = language .. ': parser not installed'
10197
if not required then
102-
vim.health.ok(message)
103-
elseif advice then
104-
vim.health.warn(message, advice)
98+
vim.health.warn(message, M.disable(language))
10599
else
106100
vim.health.error(message)
107101
end
108102
end
109103
end
110104

111105
---@private
112-
---@param filetype string
113-
function M.check_highlight(filetype)
114-
-- As nvim-treesitter is removing module support it cannot be used to check
106+
---@param language string
107+
function M.highlights(language)
108+
local files = vim.treesitter.query.get_files(language, 'highlights')
109+
if #files > 0 then
110+
for _, file in ipairs(files) do
111+
local path = vim.fn.fnamemodify(file, ':~')
112+
vim.health.ok(language .. ': highlights ' .. path)
113+
end
114+
else
115+
vim.health.error(language .. ': highlights missing')
116+
end
117+
end
118+
119+
---@private
120+
---@param language string
121+
function M.highlighter(language)
122+
-- nvim-treesitter is removing module support so cannot be used to check
115123
-- if highlights are enabled, so we create a buffer and check the state
116-
local bufnr = vim.api.nvim_create_buf(false, true)
117-
vim.bo[bufnr].filetype = filetype
118-
local has_highlighter = vim.treesitter.highlighter.active[bufnr] ~= nil
119-
vim.api.nvim_buf_delete(bufnr, { force = true })
120-
if has_highlighter then
121-
vim.health.ok(filetype .. ': highlight enabled')
124+
local buf = vim.api.nvim_create_buf(false, true)
125+
vim.bo[buf].filetype = language
126+
local ok = vim.treesitter.highlighter.active[buf] ~= nil
127+
vim.api.nvim_buf_delete(buf, { force = true })
128+
if ok then
129+
vim.health.ok(language .. ': highlighter enabled')
122130
else
123131
-- TODO(1.0): update advice once module support is removed
124-
vim.health.error(filetype .. ': highlight not enabled', {
125-
'Enable the highlight module in your nvim-treesitter config',
132+
vim.health.error(language .. ': highlighter not enabled', {
133+
'enable the highlight module in your nvim-treesitter config',
126134
"require('nvim-treesitter.configs').setup({ highlight = { enable = true } })",
127135
})
128136
end
129137
end
130138

131139
---@private
132140
---@param name string
133-
---@param required boolean
134141
---@param advice? string[]
135-
function M.check_executable(name, required, advice)
142+
function M.executable(name, advice)
136143
if vim.fn.executable(name) == 1 then
137144
vim.health.ok(name .. ': installed')
138145
else
139146
local message = name .. ': not installed'
140-
if not required then
141-
vim.health.ok(message)
142-
elseif advice then
147+
if advice then
143148
vim.health.warn(message, advice)
144149
else
145150
vim.health.error(message)
@@ -150,7 +155,7 @@ end
150155
---@private
151156
---@param name string
152157
---@param validate? fun(plugin: any): string[]?
153-
function M.check_plugin(name, validate)
158+
function M.plugin(name, validate)
154159
local has_plugin, plugin = pcall(require, name)
155160
if not has_plugin then
156161
vim.health.ok(name .. ': not installed')
@@ -166,4 +171,15 @@ function M.check_plugin(name, validate)
166171
end
167172
end
168173

174+
---@private
175+
---@param language string
176+
---@return string[]
177+
function M.disable(language)
178+
local setup = "require('render-markdown').setup"
179+
return {
180+
('disable %s support to avoid this warning'):format(language),
181+
('%s({ %s = { enabled = false } })'):format(setup, language),
182+
}
183+
end
184+
169185
return M

lua/render-markdown/render/markdown/checkbox.lua

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,39 +79,45 @@ end
7979
---@private
8080
function Render:checkbox()
8181
local node = self.data.checkbox
82+
local right = self.config.right_pad
83+
84+
-- add 1 to account for space after checkbox
85+
local width = self.context:width(node) + 1
86+
local space = width - Str.width(self.data.icon)
87+
8288
local line = self:line():text(self.data.icon, self.data.highlight)
83-
local space = self.context:width(node) + 1 - Str.width(self.data.icon)
84-
local right_pad = self.config.right_pad
8589
if space < 0 then
8690
-- not enough space to fit the icon in-place
8791
self.marks:over('check_icon', node, {
88-
virt_text = line:pad(right_pad):get(),
92+
virt_text = line:pad(right):get(),
8993
virt_text_pos = 'inline',
9094
conceal = '',
9195
}, { 0, 0, 0, 1 })
9296
else
93-
local fits = math.min(space, right_pad)
97+
local fits = math.min(space, right)
9498
space = space - fits
95-
right_pad = right_pad - fits
99+
right = right - fits
100+
96101
local row = node.start_row
97102
local start_col = node.start_col
98103
local end_col = node.end_col + 1
104+
99105
self.marks:add('check_icon', row, start_col, {
100106
end_col = end_col - space,
101107
virt_text = line:pad(fits):get(),
102108
virt_text_pos = 'overlay',
103109
})
104110
if space > 0 then
105-
-- hide extra space after the icon
111+
-- remove extra space after the icon
106112
self.marks:add('check_icon', row, end_col - space, {
107113
end_col = end_col,
108114
conceal = '',
109115
})
110116
end
111-
if right_pad > 0 then
117+
if right > 0 then
112118
-- add padding
113119
self.marks:add('check_icon', row, end_col, {
114-
virt_text = self:line():pad(right_pad):get(),
120+
virt_text = self:line():pad(right):get(),
115121
virt_text_pos = 'inline',
116122
})
117123
end

lua/render-markdown/render/markdown/heading.lua

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,24 @@ end
115115
---@private
116116
---@return integer
117117
function Render:marker()
118-
local icon, highlight = self.data.icon, {}
118+
local icon = self.data.icon
119+
local highlight = {} ---@type string[]
119120
if self.data.fg then
120121
highlight[#highlight + 1] = self.data.fg
121122
end
122123
if self.data.bg then
123124
highlight[#highlight + 1] = self.data.bg
124125
end
125126
if self.data.atx then
126-
local marker = self.data.marker
127-
-- add 1 to account for space after last `#`
128-
local width = self.context:width(marker) + 1
127+
local node = self.data.marker
128+
-- add 1 to account for space after last '#'
129+
local width = self.context:width(node) + 1
129130
if not icon or #highlight == 0 then
130131
return width
131132
end
132133
if self.config.position == 'right' then
133-
self.marks:over(true, marker, { conceal = '' }, { 0, 0, 0, 1 })
134-
self.marks:start('head_icon', marker, {
134+
self.marks:over(true, node, { conceal = '' }, { 0, 0, 0, 1 })
135+
self.marks:start('head_icon', node, {
135136
priority = 1000,
136137
virt_text = { { icon, highlight } },
137138
virt_text_pos = 'eol',
@@ -140,14 +141,14 @@ function Render:marker()
140141
else
141142
local padding = width - Str.width(icon)
142143
if self.config.position == 'inline' or padding < 0 then
143-
local added = self.marks:over('head_icon', marker, {
144+
local added = self.marks:over('head_icon', node, {
144145
virt_text = { { icon, highlight } },
145146
virt_text_pos = 'inline',
146147
conceal = '',
147148
}, { 0, 0, 0, 1 })
148149
return added and Str.width(icon) or width
149150
else
150-
self.marks:over('head_icon', marker, {
151+
self.marks:over('head_icon', node, {
151152
virt_text = { { Str.pad(padding) .. icon, highlight } },
152153
virt_text_pos = 'overlay',
153154
})

0 commit comments

Comments
 (0)