aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/health.lua
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-05-24 19:18:11 +0000
committerJosh Rahm <joshuarahm@gmail.com>2024-05-24 19:18:11 +0000
commitff7ed8f586589d620a806c3758fac4a47a8e7e15 (patch)
tree729bbcb92231538fa61dab6c3d890b025484b7f5 /runtime/lua/vim/health.lua
parent376914f419eb08fdf4c1a63a77e1f035898a0f10 (diff)
parent28c04948a1c887a1cc0cb64de79fa32631700466 (diff)
downloadrneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.gz
rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.tar.bz2
rneovim-ff7ed8f586589d620a806c3758fac4a47a8e7e15.zip
Merge remote-tracking branch 'upstream/master' into mix_20240309
Diffstat (limited to 'runtime/lua/vim/health.lua')
-rw-r--r--runtime/lua/vim/health.lua224
1 files changed, 114 insertions, 110 deletions
diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua
index f6f7abef8f..f40f04a064 100644
--- a/runtime/lua/vim/health.lua
+++ b/runtime/lua/vim/health.lua
@@ -1,43 +1,96 @@
+--- @brief
+---<pre>help
+--- health.vim 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
+---
+--- :checkhealth
+--- <
+--- Plugin authors are encouraged to write new healthchecks. |health-dev|
+---
+--- Commands *health-commands*
+---
+--- *:che* *:checkhealth*
+--- :che[ckhealth] Run all healthchecks.
+--- *E5009*
+--- Nvim depends on |$VIMRUNTIME|, 'runtimepath' and 'packpath' to
+--- find the standard "runtime files" for syntax highlighting,
+--- filetype-specific behavior, and standard plugins (including
+--- :checkhealth). If the runtime files cannot be found then
+--- those features will not work.
+---
+--- :che[ckhealth] {plugins}
+--- Run healthcheck(s) for one or more plugins. E.g. to run only
+--- the standard Nvim healthcheck: >vim
+--- :checkhealth vim.health
+--- <
+--- To run the healthchecks for the "foo" and "bar" plugins
+--- (assuming they are on 'runtimepath' and they have implemented
+--- the Lua `require("foo.health").check()` interface): >vim
+--- :checkhealth foo bar
+--- <
+--- To run healthchecks for Lua submodules, use dot notation or
+--- "*" to refer to all submodules. For example Nvim provides
+--- `vim.lsp` and `vim.treesitter`: >vim
+--- :checkhealth vim.lsp vim.treesitter
+--- :checkhealth vim*
+--- <
+---
+--- Create a healthcheck *health-dev* *vim.health*
+---
+--- Healthchecks are functions that check the user environment, configuration, or
+--- any other prerequisites that a plugin cares about. Nvim ships with
+--- healthchecks in:
+--- - $VIMRUNTIME/autoload/health/
+--- - $VIMRUNTIME/lua/vim/lsp/health.lua
+--- - $VIMRUNTIME/lua/vim/treesitter/health.lua
+--- - and more...
+---
+--- 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
+--- |:checkhealth| will automatically find and invoke the function.
+---
+--- For example if your plugin is named "foo", define your healthcheck module at
+--- one of these locations (on 'runtimepath'):
+--- - lua/foo/health/init.lua
+--- - lua/foo/health.lua
+---
+--- If your plugin also provides a submodule named "bar" for which you want
+--- a separate healthcheck, define the healthcheck at one of these locations:
+--- - lua/foo/bar/health/init.lua
+--- - lua/foo/bar/health.lua
+---
+--- All such health modules must return a Lua table containing a `check()`
+--- function.
+---
+--- Copy this sample code into `lua/foo/health.lua`, replacing "foo" in the path
+--- with your plugin name: >lua
+---
+--- 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
+---
+--- return M
+---</pre>
+
local M = {}
local s_output = {} ---@type string[]
---- Returns the fold text of the current healthcheck section
-function M.foldtext()
- local foldtext = vim.fn.foldtext()
-
- if vim.bo.filetype ~= 'checkhealth' then
- return foldtext
- end
-
- if vim.b.failedchecks == nil then
- vim.b.failedchecks = vim.empty_dict()
- end
-
- if vim.b.failedchecks[foldtext] == nil then
- local warning = '- WARNING '
- local warninglen = string.len(warning)
- local err = '- ERROR '
- local errlen = string.len(err)
- local failedchecks = vim.b.failedchecks
- failedchecks[foldtext] = false
-
- local foldcontent = vim.api.nvim_buf_get_lines(0, vim.v.foldstart - 1, vim.v.foldend, false)
- for _, line in ipairs(foldcontent) do
- if string.sub(line, 1, warninglen) == warning or string.sub(line, 1, errlen) == err then
- failedchecks[foldtext] = true
- break
- end
- end
-
- vim.b.failedchecks = failedchecks
- end
-
- return vim.b.failedchecks[foldtext] and '+WE' .. foldtext:sub(4) or foldtext
-end
-
---- @param path string path to search for the healthcheck
---- @return string[] { name, func, type } representing a healthcheck
+-- From a path return a list [{name}, {func}, {type}] representing a healthcheck
local function filepath_to_healthcheck(path)
path = vim.fs.normalize(path)
local name --- @type string
@@ -178,7 +231,9 @@ local function collect_output(output)
vim.list_extend(s_output, vim.split(output, '\n'))
end
---- Starts a new report.
+--- Starts a new report. Most plugins should call this only once, but if
+--- you want different sections to appear in your report, call this once
+--- per section.
---
--- @param name string
function M.start(name)
@@ -186,7 +241,7 @@ function M.start(name)
collect_output(input)
end
---- Reports a message in the current section.
+--- Reports an informational message.
---
--- @param msg string
function M.info(msg)
@@ -194,7 +249,7 @@ function M.info(msg)
collect_output(input)
end
---- Reports a successful healthcheck.
+--- Reports a "success" message.
---
--- @param msg string
function M.ok(msg)
@@ -202,7 +257,7 @@ function M.ok(msg)
collect_output(input)
end
---- Reports a health warning.
+--- Reports a warning.
---
--- @param msg string
--- @param ... string|string[] Optional advice
@@ -211,7 +266,7 @@ function M.warn(msg, ...)
collect_output(input)
end
---- Reports a failed healthcheck.
+--- Reports an error.
---
--- @param msg string
--- @param ... string|string[] Optional advice
@@ -220,54 +275,7 @@ function M.error(msg, ...)
collect_output(input)
end
---- @param type string
-local function deprecate(type)
- local before = string.format('vim.health.report_%s()', type)
- local after = string.format('vim.health.%s()', type)
- local message = vim.deprecate(before, after, '0.11')
- if message then
- M.warn(message)
- end
- vim.cmd.redraw()
- vim.print('Running healthchecks...')
-end
-
---- @deprecated
---- @param name string
-function M.report_start(name)
- deprecate('start')
- M.start(name)
-end
-
---- @deprecated
---- @param msg string
-function M.report_info(msg)
- deprecate('info')
- M.info(msg)
-end
-
---- @deprecated
---- @param msg string
-function M.report_ok(msg)
- deprecate('ok')
- M.ok(msg)
-end
-
---- @deprecated
---- @param msg string
-function M.report_warn(msg, ...)
- deprecate('warn')
- M.warn(msg, ...)
-end
-
---- @deprecated
---- @param msg string
-function M.report_error(msg, ...)
- deprecate('error')
- M.error(msg, ...)
-end
-
-function M.provider_disabled(provider)
+function M._provider_disabled(provider)
local loaded_var = 'loaded_' .. provider .. '_provider'
local v = vim.g[loaded_var]
if v == 0 then
@@ -307,7 +315,7 @@ local function shellify(cmd)
return table.concat(escaped, ' ')
end
-function M.cmd_ok(cmd)
+function M._cmd_ok(cmd)
local out = vim.fn.system(cmd)
return vim.v.shell_error == 0, out
end
@@ -320,7 +328,7 @@ end
--- - stderr (boolean): Append stderr to stdout
--- - ignore_error (boolean): If true, ignore error output
--- - timeout (number): Number of seconds to wait before timing out (default 30)
-function M.system(cmd, args)
+function M._system(cmd, args)
args = args or {}
local stdin = args.stdin or ''
local stderr = vim.F.if_nil(args.stderr, false)
@@ -341,7 +349,7 @@ function M.system(cmd, args)
if jobid < 1 then
local message =
- string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.loop.cwd())
+ string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.uv.cwd())
error(message)
return opts.output, 1
end
@@ -360,7 +368,7 @@ function M.system(cmd, args)
jobid,
shell_error_code,
shellify(cmd),
- vim.loop.cwd()
+ vim.uv.cwd()
)
if opts.output:find('%S') then
emsg = string.format('%s\noutput: %s', emsg, opts.output)
@@ -386,7 +394,7 @@ local path2name = function(path)
path = path:gsub('^.*/lua/', '')
-- Remove the filename (health.lua)
- path = vim.fn.fnamemodify(path, ':h')
+ path = vim.fs.dirname(path)
-- Change slashes to dots
path = path:gsub('/', '.')
@@ -401,17 +409,20 @@ end
local PATTERNS = { '/autoload/health/*.vim', '/lua/**/**/health.lua', '/lua/**/**/health/init.lua' }
--- :checkhealth completion function used by cmdexpand.c get_healthcheck_names()
M._complete = function()
- local names = vim.tbl_flatten(vim.tbl_map(function(pattern)
- return vim.tbl_map(path2name, vim.api.nvim_get_runtime_file(pattern, true))
- end, PATTERNS))
- -- Remove duplicates
- local unique = {}
- vim.tbl_map(function(f)
- unique[f] = true
- end, names)
+ local unique = vim
+ .iter(vim.tbl_map(function(pattern)
+ return vim.tbl_map(path2name, vim.api.nvim_get_runtime_file(pattern, true))
+ end, PATTERNS))
+ :flatten()
+ :fold({}, function(t, name)
+ t[name] = true -- Remove duplicates
+ return t
+ end)
-- vim.health is this file, which is not a healthcheck
unique['vim'] = nil
- return vim.tbl_keys(unique)
+ local rv = vim.tbl_keys(unique)
+ table.sort(rv)
+ return rv
end
--- Runs the specified healthchecks.
@@ -497,11 +508,4 @@ function M._check(mods, plugin_names)
vim.print('')
end
-local fn_bool = function(key)
- return function(...)
- return vim.fn[key](...) == 1
- end
-end
-M.executable = fn_bool('executable')
-
return M