diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2024-11-19 22:57:13 +0000 |
commit | 9be89f131f87608f224f0ee06d199fcd09d32176 (patch) | |
tree | 11022dcfa9e08cb4ac5581b16734196128688d48 /runtime/lua/vim/health.lua | |
parent | ff7ed8f586589d620a806c3758fac4a47a8e7e15 (diff) | |
parent | 88085c2e80a7e3ac29aabb6b5420377eed99b8b6 (diff) | |
download | rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.gz rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.tar.bz2 rneovim-9be89f131f87608f224f0ee06d199fcd09d32176.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.lua | 137 |
1 files changed, 19 insertions, 118 deletions
diff --git a/runtime/lua/vim/health.lua b/runtime/lua/vim/health.lua index f40f04a064..52a7a13966 100644 --- a/runtime/lua/vim/health.lua +++ b/runtime/lua/vim/health.lua @@ -1,6 +1,6 @@ --- @brief ---<pre>help ---- health.vim 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 --- with healthchecks for configuration, performance, python support, ruby --- support, clipboard support, and more. @@ -39,7 +39,7 @@ --- :checkhealth vim* --- < --- ---- Create a healthcheck *health-dev* *vim.health* +--- Create a healthcheck *health-dev* --- --- Healthchecks are functions that check the user environment, configuration, or --- any other prerequisites that a plugin cares about. Nvim ships with @@ -104,10 +104,10 @@ local function filepath_to_healthcheck(path) local subpath = path:gsub('.*lua/', '') if vim.fs.basename(subpath) == 'health.lua' then -- */health.lua - name = assert(vim.fs.dirname(subpath)) + name = vim.fs.dirname(subpath) else -- */health/init.lua - name = assert(vim.fs.dirname(assert(vim.fs.dirname(subpath)))) + name = vim.fs.dirname(vim.fs.dirname(subpath)) end name = name:gsub('/', '.') @@ -275,114 +275,6 @@ function M.error(msg, ...) collect_output(input) end -function M._provider_disabled(provider) - local loaded_var = 'loaded_' .. provider .. '_provider' - local v = vim.g[loaded_var] - if v == 0 then - M.info('Disabled (' .. loaded_var .. '=' .. v .. ').') - return true - end - return false -end - --- Handler for s:system() function. -local function system_handler(self, _, data, event) - if event == 'stderr' then - if self.add_stderr_to_output then - self.output = self.output .. table.concat(data, '') - else - self.stderr = self.stderr .. table.concat(data, '') - end - elseif event == 'stdout' then - self.output = self.output .. table.concat(data, '') - end -end - --- Attempts to construct a shell command from an args list. --- Only for display, to help users debug a failed command. -local function shellify(cmd) - if type(cmd) ~= 'table' then - return cmd - end - local escaped = {} - for i, v in ipairs(cmd) do - if v:match('[^A-Za-z_/.-]') then - escaped[i] = vim.fn.shellescape(v) - else - escaped[i] = v - end - end - return table.concat(escaped, ' ') -end - -function M._cmd_ok(cmd) - local out = vim.fn.system(cmd) - return vim.v.shell_error == 0, out -end - ---- Run a system command and timeout after 30 seconds. ---- ---- @param cmd table List of command arguments to execute ---- @param args? table Optional arguments: ---- - stdin (string): Data to write to the job's stdin ---- - 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) - args = args or {} - local stdin = args.stdin or '' - local stderr = vim.F.if_nil(args.stderr, false) - local ignore_error = vim.F.if_nil(args.ignore_error, false) - - local shell_error_code = 0 - local opts = { - add_stderr_to_output = stderr, - output = '', - stderr = '', - on_stdout = system_handler, - on_stderr = system_handler, - on_exit = function(_, data) - shell_error_code = data - end, - } - local jobid = vim.fn.jobstart(cmd, opts) - - if jobid < 1 then - local message = - string.format('Command error (job=%d): %s (in %s)', jobid, shellify(cmd), vim.uv.cwd()) - error(message) - return opts.output, 1 - end - - if stdin:find('^%s$') then - vim.fn.chansend(jobid, stdin) - end - - local res = vim.fn.jobwait({ jobid }, vim.F.if_nil(args.timeout, 30) * 1000) - if res[1] == -1 then - error('Command timed out: ' .. shellify(cmd)) - vim.fn.jobstop(jobid) - elseif shell_error_code ~= 0 and not ignore_error then - local emsg = string.format( - 'Command error (job=%d, exit code %d): %s (in %s)', - jobid, - shell_error_code, - shellify(cmd), - vim.uv.cwd() - ) - if opts.output:find('%S') then - emsg = string.format('%s\noutput: %s', emsg, opts.output) - end - if opts.stderr:find('%S') then - emsg = string.format('%s\nstderr: %s', emsg, opts.stderr) - end - error(emsg) - end - - -- return opts.output - return vim.trim(vim.fn.system(cmd)), shell_error_code -end - local path2name = function(path) if path:match('%.lua$') then -- Lua: transform "../lua/vim/lsp/health.lua" into "vim.lsp" @@ -393,8 +285,8 @@ local path2name = function(path) -- Remove everything up to the last /lua/ folder path = path:gsub('^.*/lua/', '') - -- Remove the filename (health.lua) - path = vim.fs.dirname(path) + -- Remove the filename (health.lua) or (health/init.lua) + path = vim.fs.dirname(path:gsub('/init%.lua$', '')) -- Change slashes to dots path = path:gsub('/', '.') @@ -409,11 +301,13 @@ 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 unique = vim + local unique = vim ---@type table<string,boolean> + ---@param pattern string .iter(vim.tbl_map(function(pattern) return vim.tbl_map(path2name, vim.api.nvim_get_runtime_file(pattern, true)) end, PATTERNS)) :flatten() + ---@param t table<string,boolean> :fold({}, function(t, name) t[name] = true -- Remove duplicates return t @@ -472,7 +366,7 @@ function M._check(mods, plugin_names) vim.fn.call(func, {}) else local f = assert(loadstring(func)) - local ok, output = pcall(f) + local ok, output = pcall(f) ---@type boolean, string if not ok then M.error( string.format('Failed to run healthcheck for "%s" plugin. Exception:\n%s\n', name, output) @@ -485,7 +379,14 @@ function M._check(mods, plugin_names) s_output = {} M.error('The healthcheck report for "' .. name .. '" plugin is empty.') end - local header = { string.rep('=', 78), name .. ': ' .. func, '' } + + local header = { + string.rep('=', 78), + -- Example: `foo.health: [ …] require("foo.health").check()` + ('%s: %s%s'):format(name, (' '):rep(76 - name:len() - func:len()), func), + '', + } + -- remove empty line after header from report_start if s_output[1] == '' then local tmp = {} ---@type string[] @@ -499,7 +400,7 @@ function M._check(mods, plugin_names) end s_output[#s_output + 1] = '' s_output = vim.list_extend(header, s_output) - vim.fn.append('$', s_output) + vim.fn.append(vim.fn.line('$'), s_output) vim.cmd.redraw() end |