feat(checkhealth): trigger FileType event after showing report

Problem:
`FileType` event is fired before checkhealth report is finished, so
user can't override report settings or contents.
https://github.com/neovim/neovim/pull/33172#issuecomment-2833513916

Solution:
- Trigger FileType event later.
- Document how to remove emojis.
This commit is contained in:
Justin M. Keyes
2025-04-27 10:32:25 -07:00
parent 95ee908c40
commit ad7211ac8f
4 changed files with 129 additions and 83 deletions

View File

@ -9,18 +9,18 @@
============================================================================== ==============================================================================
Checkhealth *vim.health* *health* Checkhealth *vim.health* *health*
vim.health is a minimal framework to help users troubleshoot configuration and vim.health is a minimal framework to help users troubleshoot configuration and
any other environment conditions that a plugin might care about. Nvim ships any other environment conditions that a plugin might care about. Nvim ships
with healthchecks for configuration, performance, python support, ruby with healthchecks for configuration, performance, python support, ruby
support, clipboard support, and more. support, clipboard support, and more.
To run all healthchecks, use: >vim To run all healthchecks, use: >vim
:checkhealth
:checkhealth
< <
Plugin authors are encouraged to write new healthchecks. |health-dev| Plugin authors are encouraged to write new healthchecks. |health-dev|
COMMANDS *health-commands* COMMANDS *health-commands*
*:che* *:checkhealth* *:che* *:checkhealth*
@ -56,7 +56,6 @@ Local mappings in the healthcheck buffer:
q Closes the window. q Closes the window.
Global configuration: Global configuration:
*g:health* *g:health*
g:health Dictionary with the following optional keys: g:health Dictionary with the following optional keys:
- `style` (`'float'|nil`) Set to "float" to display :checkhealth in - `style` (`'float'|nil`) Set to "float" to display :checkhealth in
@ -65,16 +64,26 @@ g:health Dictionary with the following optional keys:
Example: >lua Example: >lua
vim.g.health = { style = 'float' } vim.g.health = { style = 'float' }
Local configuration:
Checkhealth sets its buffer filetype to "checkhealth". You can customize the
buffer by handling the |FileType| event. For example if you don't want emojis
in the health report: >vim
autocmd FileType checkhealth :set modifiable | silent! %s/\v( ?[^\x00-\x7F])//g
<
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
Create a healthcheck *health-dev* Create a healthcheck *health-dev*
Healthchecks are functions that check the user environment, configuration, or Healthchecks are functions that check the user environment, configuration, or
any other prerequisites that a plugin cares about. Nvim ships with any other prerequisites that a plugin cares about. Nvim ships with
healthchecks in: healthchecks in:
- $VIMRUNTIME/autoload/health/ $VIMRUNTIME/autoload/health/
- $VIMRUNTIME/lua/vim/lsp/health.lua $VIMRUNTIME/lua/vim/lsp/health.lua
- $VIMRUNTIME/lua/vim/treesitter/health.lua $VIMRUNTIME/lua/vim/treesitter/health.lua
- and more... and more...
To add a new healthcheck for your own plugin, simply create a "health.lua" To add a new healthcheck for your own plugin, simply create a "health.lua"
module on 'runtimepath' that returns a table with a "check()" function. Then module on 'runtimepath' that returns a table with a "check()" function. Then
@ -82,35 +91,35 @@ module on 'runtimepath' that returns a table with a "check()" function. Then
For example if your plugin is named "foo", define your healthcheck module at For example if your plugin is named "foo", define your healthcheck module at
one of these locations (on 'runtimepath'): one of these locations (on 'runtimepath'):
- lua/foo/health/init.lua lua/foo/health/init.lua
- lua/foo/health.lua lua/foo/health.lua
If your plugin also provides a submodule named "bar" for which you want If your plugin also provides a submodule named "bar" for which you want a
a separate healthcheck, define the healthcheck at one of these locations: separate healthcheck, define the healthcheck at one of these locations:
- lua/foo/bar/health/init.lua lua/foo/bar/health/init.lua
- lua/foo/bar/health.lua lua/foo/bar/health.lua
All such health modules must return a Lua table containing a `check()` All such health modules must return a Lua table containing a `check()`
function. function.
Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path
with your plugin name: >lua with your plugin name: >lua
local M = {}
local M = {} M.check = function()
vim.health.start("foo report")
-- make sure setup function parameters are ok
if check_setup() then
vim.health.ok("Setup is correct")
else
vim.health.error("Setup is incorrect")
end
-- do some more checking
-- ...
end
M.check = function() return M
vim.health.start("foo report") <
-- make sure setup function parameters are ok
if check_setup() then
vim.health.ok("Setup is correct")
else
vim.health.error("Setup is incorrect")
end
-- do some more checking
-- ...
end
return M
error({msg}, {...}) *vim.health.error()* error({msg}, {...}) *vim.health.error()*

View File

@ -343,6 +343,8 @@ PLUGINS
• 'commentstring' values can now be specified in a Treesitter capture's • 'commentstring' values can now be specified in a Treesitter capture's
`bo.commentstring` metadata field, providing finer grained support for `bo.commentstring` metadata field, providing finer grained support for
languages like `JSX`. languages like `JSX`.
• Customize :checkhealth by handling a `FileType checkhealth` event.
|health-usage|
STARTUP STARTUP

View File

@ -1,16 +1,16 @@
--- @brief --- @brief
---<pre>help
--- vim.health is a minimal framework to help users troubleshoot configuration and
--- any other environment conditions that a plugin might care about. Nvim ships
--- with healthchecks for configuration, performance, python support, ruby
--- support, clipboard support, and more.
--- ---
--- To run all healthchecks, use: >vim --- vim.health is a minimal framework to help users troubleshoot configuration and any other
--- environment conditions that a plugin might care about. Nvim ships with healthchecks for
--- configuration, performance, python support, ruby support, clipboard support, and more.
--- ---
--- :checkhealth --- To run all healthchecks, use:
--- < --- ```vim
--- :checkhealth
--- ```
--- Plugin authors are encouraged to write new healthchecks. |health-dev| --- Plugin authors are encouraged to write new healthchecks. |health-dev|
--- ---
---<pre>help
--- COMMANDS *health-commands* --- COMMANDS *health-commands*
--- ---
--- *:che* *:checkhealth* --- *:che* *:checkhealth*
@ -46,7 +46,6 @@
--- q Closes the window. --- q Closes the window.
--- ---
--- Global configuration: --- Global configuration:
---
--- *g:health* --- *g:health*
--- g:health Dictionary with the following optional keys: --- g:health Dictionary with the following optional keys:
--- - `style` (`'float'|nil`) Set to "float" to display :checkhealth in --- - `style` (`'float'|nil`) Set to "float" to display :checkhealth in
@ -55,53 +54,64 @@
--- Example: >lua --- Example: >lua
--- vim.g.health = { style = 'float' } --- vim.g.health = { style = 'float' }
--- ---
---</pre>
---
--- Local configuration:
---
--- Checkhealth sets its buffer filetype to "checkhealth". You can customize the buffer by handling
--- the |FileType| event. For example if you don't want emojis in the health report:
--- ```vim
--- autocmd FileType checkhealth :set modifiable | silent! %s/\v( ?[^\x00-\x7F])//g
--- ```
---
---<pre>help
--- -------------------------------------------------------------------------------- --- --------------------------------------------------------------------------------
--- Create a healthcheck *health-dev* --- Create a healthcheck *health-dev*
---</pre>
--- ---
--- Healthchecks are functions that check the user environment, configuration, or --- Healthchecks are functions that check the user environment, configuration, or any other
--- any other prerequisites that a plugin cares about. Nvim ships with --- prerequisites that a plugin cares about. Nvim ships with healthchecks in:
--- healthchecks in: --- - $VIMRUNTIME/autoload/health/
--- - $VIMRUNTIME/autoload/health/ --- - $VIMRUNTIME/lua/vim/lsp/health.lua
--- - $VIMRUNTIME/lua/vim/lsp/health.lua --- - $VIMRUNTIME/lua/vim/treesitter/health.lua
--- - $VIMRUNTIME/lua/vim/treesitter/health.lua --- - and more...
--- - and more...
--- ---
--- To add a new healthcheck for your own plugin, simply create a "health.lua" --- To add a new healthcheck for your own plugin, simply create a "health.lua" module on
--- module on 'runtimepath' that returns a table with a "check()" function. Then --- 'runtimepath' that returns a table with a "check()" function. Then |:checkhealth| will
--- |:checkhealth| will automatically find and invoke the function. --- automatically find and invoke the function.
--- ---
--- For example if your plugin is named "foo", define your healthcheck module at --- For example if your plugin is named "foo", define your healthcheck module at
--- one of these locations (on 'runtimepath'): --- one of these locations (on 'runtimepath'):
--- - lua/foo/health/init.lua --- - lua/foo/health/init.lua
--- - lua/foo/health.lua --- - lua/foo/health.lua
--- ---
--- If your plugin also provides a submodule named "bar" for which you want --- If your plugin also provides a submodule named "bar" for which you want a separate healthcheck,
--- a separate healthcheck, define the healthcheck at one of these locations: --- define the healthcheck at one of these locations:
--- - lua/foo/bar/health/init.lua --- - lua/foo/bar/health/init.lua
--- - lua/foo/bar/health.lua --- - lua/foo/bar/health.lua
--- ---
--- All such health modules must return a Lua table containing a `check()` --- All such health modules must return a Lua table containing a `check()` function.
--- function.
--- ---
--- Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path --- Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path with your plugin
--- with your plugin name: >lua --- name:
--- ---
--- local M = {} --- ```lua
--- local M = {}
--- ---
--- M.check = function() --- M.check = function()
--- vim.health.start("foo report") --- vim.health.start("foo report")
--- -- make sure setup function parameters are ok --- -- make sure setup function parameters are ok
--- if check_setup() then --- if check_setup() then
--- vim.health.ok("Setup is correct") --- vim.health.ok("Setup is correct")
--- else --- else
--- vim.health.error("Setup is incorrect") --- vim.health.error("Setup is incorrect")
--- end --- end
--- -- do some more checking --- -- do some more checking
--- -- ... --- -- ...
--- end --- end
--- ---
--- return M --- return M
---</pre> --- ```
local M = {} local M = {}
@ -385,7 +395,6 @@ function M._check(mods, plugin_names)
vim.cmd.bwipe('health://') vim.cmd.bwipe('health://')
end end
vim.cmd.file('health://') vim.cmd.file('health://')
vim.cmd.setfiletype('checkhealth')
-- This should only happen when doing `:checkhealth vim` -- This should only happen when doing `:checkhealth vim`
if next(healthchecks) == nil then if next(healthchecks) == nil then
@ -463,6 +472,7 @@ function M._check(mods, plugin_names)
-- Once we're done writing checks, set nomodifiable. -- Once we're done writing checks, set nomodifiable.
vim.bo[bufnr].modifiable = false vim.bo[bufnr].modifiable = false
vim.cmd.setfiletype('checkhealth')
end end
return M return M

View File

@ -78,6 +78,15 @@ describe(':checkhealth', function()
]]) ]])
) )
end) end)
it("vim.provider works with a misconfigured 'shell'", function()
clear()
command([[set shell=echo\ WRONG!!!]])
command('let g:loaded_perl_provider = 0')
command('let g:loaded_python3_provider = 0')
command('checkhealth vim.provider')
eq(nil, string.match(curbuf_contents(), 'WRONG!!!'))
end)
end) end)
describe('vim.health', function() describe('vim.health', function()
@ -109,6 +118,33 @@ describe('vim.health', function()
]]) ]])
end) end)
it('user FileType handler can modify report', function()
-- Define a FileType autocmd that removes emoji chars.
source [[
autocmd FileType checkhealth :set modifiable | silent! %s/\v( ?[^\x00-\x7F])//g
checkhealth full_render
]]
n.expect([[
==============================================================================
test_plug.full_render: 1 1
report 1 ~
- OK life is fine
- WARNING no what installed
- ADVICE:
- pip what
- make what
report 2 ~
- stuff is stable
- ERROR why no hardcopy
- ADVICE:
- :help |:hardcopy|
- :help |:TOhtml|
]])
end)
it('concatenates multiple reports', function() it('concatenates multiple reports', function()
command('checkhealth success1 success2 test_plug') command('checkhealth success1 success2 test_plug')
n.expect([[ n.expect([[
@ -245,17 +281,6 @@ describe('vim.health', function()
end) end)
end) end)
describe(':checkhealth vim.provider', function()
it("works correctly with a wrongly configured 'shell'", function()
clear()
command([[set shell=echo\ WRONG!!!]])
command('let g:loaded_perl_provider = 0')
command('let g:loaded_python3_provider = 0')
command('checkhealth vim.provider')
eq(nil, string.match(curbuf_contents(), 'WRONG!!!'))
end)
end)
describe(':checkhealth window', function() describe(':checkhealth window', function()
before_each(function() before_each(function()
clear { args = { '-u', 'NORC', '+set runtimepath+=test/functional/fixtures' } } clear { args = { '-u', 'NORC', '+set runtimepath+=test/functional/fixtures' } }