feat(checkhealth): check runtime ($VIMRUNTIME)

Move man/health.lua into the "runtime" check.

fix #20696
This commit is contained in:
Justin M. Keyes
2022-10-30 06:41:28 +01:00
parent 3213bc36c5
commit cc7c378bf3
4 changed files with 113 additions and 64 deletions

View File

@@ -1,20 +0,0 @@
local M = {}
local report_ok = vim.fn['health#report_ok']
local report_error = vim.fn['health#report_error']
local function check_runtime_file(name)
local path = vim.env.VIMRUNTIME .. '/' .. name
if vim.loop.fs_stat(path) then
report_error(string.format('%s detected. Please delete %s', name, path))
else
report_ok(string.format('%s not in $VIMRUNTIME', name))
end
end
function M.check()
check_runtime_file('plugin/man.vim')
check_runtime_file('autoload/man.vim')
end
return M

View File

@@ -3,68 +3,134 @@ local health = require('vim.health')
local suggest_faq = 'https://github.com/neovim/neovim/wiki/FAQ' local suggest_faq = 'https://github.com/neovim/neovim/wiki/FAQ'
local function check_runtime()
health.report_start('Runtime')
-- Files from an old installation.
local bad_files = {
['plugin/man.vim'] = false,
['scripts.vim'] = false,
['autoload/man.vim'] = false,
}
local bad_files_msg = ''
for k, _ in pairs(bad_files) do
local path = ('%s/%s'):format(vim.env.VIMRUNTIME, k)
if vim.loop.fs_stat(path) then
bad_files[k] = true
bad_files_msg = ('%s%s\n'):format(bad_files_msg, path)
end
end
local ok = (bad_files_msg == '')
local info = ok and health.report_ok or health.report_info
info(string.format('$VIMRUNTIME: %s', vim.env.VIMRUNTIME))
if not ok then
health.report_error(
string.format(
'$VIMRUNTIME has files from an old installation (this can cause weird behavior):\n%s',
bad_files_msg
),
{ 'Delete $VIMRUNTIME (or uninstall Nvim), then reinstall Nvim.' }
)
end
end
local function check_config() local function check_config()
health.report_start('Configuration') health.report_start('Configuration')
local ok = true local ok = true
local empty = function(o) return 0 ~= vim.fn.empty(o) end local empty = function(o)
local filereadable = function(o) return 0 ~= vim.fn.filereadable(o) end return 0 ~= vim.fn.empty(o)
local filewritable = function(o) return 0 ~= vim.fn.filewritable(o) end end
local filereadable = function(o)
return 0 ~= vim.fn.filereadable(o)
end
local filewritable = function(o)
return 0 ~= vim.fn.filewritable(o)
end
local vimrc = empty(vim.env.MYVIMRC) and vim.fn.stdpath('config')..'/init.vim' or vim.env.MYVIMRC local vimrc = (
empty(vim.env.MYVIMRC) and vim.fn.stdpath('config') .. '/init.vim' or vim.env.MYVIMRC
)
if not filereadable(vimrc) then if not filereadable(vimrc) then
ok = false ok = false
local has_vim = filereadable(vim.fn.expand('~/.vimrc')) local has_vim = filereadable(vim.fn.expand('~/.vimrc'))
health.report_warn((-1 == vim.fn.getfsize(vimrc) and 'Missing' or 'Unreadable')..' user config file: '..vimrc, health.report_warn(
{ has_vim and ':help nvim-from-vim' or ':help init.vim' }) (-1 == vim.fn.getfsize(vimrc) and 'Missing' or 'Unreadable') .. ' user config file: ' .. vimrc,
{ has_vim and ':help nvim-from-vim' or ':help init.vim' }
)
end end
-- If $VIM is empty we don't care. Else make sure it is valid. -- If $VIM is empty we don't care. Else make sure it is valid.
if not empty(vim.env.VIM) and not filereadable(vim.env.VIM..'/runtime/doc/nvim.txt') then if not empty(vim.env.VIM) and not filereadable(vim.env.VIM .. '/runtime/doc/nvim.txt') then
ok = false ok = false
health.report_error('$VIM is invalid: '..vim.env.VIM) health.report_error('$VIM is invalid: ' .. vim.env.VIM)
end end
if 1 == vim.fn.exists('$NVIM_TUI_ENABLE_CURSOR_SHAPE') then if 1 == vim.fn.exists('$NVIM_TUI_ENABLE_CURSOR_SHAPE') then
ok = false ok = false
health.report_warn('$NVIM_TUI_ENABLE_CURSOR_SHAPE is ignored in Nvim 0.2+', health.report_warn('$NVIM_TUI_ENABLE_CURSOR_SHAPE is ignored in Nvim 0.2+', {
{ "Use the 'guicursor' option to configure cursor shape. :help 'guicursor'", "Use the 'guicursor' option to configure cursor shape. :help 'guicursor'",
'https://github.com/neovim/neovim/wiki/Following-HEAD#20170402' }) 'https://github.com/neovim/neovim/wiki/Following-HEAD#20170402',
})
end end
if vim.v.ctype == 'C' then if vim.v.ctype == 'C' then
ok = false ok = false
health.report_error('Locale does not support UTF-8. Unicode characters may not display correctly.' health.report_error(
..("\n$LANG=%s $LC_ALL=%s $LC_CTYPE=%s"):format(vim.env.LANG, vim.env.LC_ALL, vim.env.LC_CTYPE), 'Locale does not support UTF-8. Unicode characters may not display correctly.'
{ 'If using tmux, try the -u option.', .. ('\n$LANG=%s $LC_ALL=%s $LC_CTYPE=%s'):format(
'Ensure that your terminal/shell/tmux/etc inherits the environment, or set $LANG explicitly.' , vim.env.LANG,
'Configure your system locale.' }) vim.env.LC_ALL,
vim.env.LC_CTYPE
),
{
'If using tmux, try the -u option.',
'Ensure that your terminal/shell/tmux/etc inherits the environment, or set $LANG explicitly.',
'Configure your system locale.',
}
)
end end
if vim.o.paste == 1 then if vim.o.paste == 1 then
ok = false ok = false
health.report_error("'paste' is enabled. This option is only for pasting text.\nIt should not be set in your config.", health.report_error(
{ 'Remove `set paste` from your init.vim, if applicable.', "'paste' is enabled. This option is only for pasting text.\nIt should not be set in your config.",
'Check `:verbose set paste?` to see if a plugin or script set the option.', }) {
'Remove `set paste` from your init.vim, if applicable.',
'Check `:verbose set paste?` to see if a plugin or script set the option.',
}
)
end end
local writeable = true local writeable = true
local shadaopt = vim.fn.split(vim.o.shada, ',') local shadaopt = vim.fn.split(vim.o.shada, ',')
local shadafile = (empty(vim.o.shada) local shadafile = (
and vim.o.shada empty(vim.o.shada) and vim.o.shada
or vim.fn.substitute(vim.fn.matchstr(shadaopt[#shadaopt], '^n.\\+'), '^n', '', '')) or vim.fn.substitute(vim.fn.matchstr(shadaopt[#shadaopt], '^n.\\+'), '^n', '', '')
shadafile = (empty(vim.o.shadafile) )
and (empty(shadafile) and vim.fn.stdpath('state')..'/shada/main.shada' or vim.fn.expand(shadafile)) shadafile = (
or (vim.o.shadafile == 'NONE' and '' or vim.o.shadafile)) empty(vim.o.shadafile)
and (empty(shadafile) and vim.fn.stdpath('state') .. '/shada/main.shada' or vim.fn.expand(
shadafile
))
or (vim.o.shadafile == 'NONE' and '' or vim.o.shadafile)
)
if not empty(shadafile) and empty(vim.fn.glob(shadafile)) then if not empty(shadafile) and empty(vim.fn.glob(shadafile)) then
-- Since this may be the first time Nvim has been run, try to create a shada file. -- Since this may be the first time Nvim has been run, try to create a shada file.
if not pcall(vim.cmd.wshada) then if not pcall(vim.cmd.wshada) then
writeable = false writeable = false
end end
end end
if not writeable or (not empty(shadafile) and (not filereadable(shadafile) or not filewritable(shadafile))) then if
not writeable
or (not empty(shadafile) and (not filereadable(shadafile) or not filewritable(shadafile)))
then
ok = false ok = false
health.report_error('shada file is not ' health.report_error(
..((not writeable or filereadable(shadafile)) and 'writeable' or 'readable')..':\n'..shadafile) 'shada file is not '
.. ((not writeable or filereadable(shadafile)) and 'writeable' or 'readable')
.. ':\n'
.. shadafile
)
end end
if ok then if ok then
@@ -75,7 +141,7 @@ end
local function check_performance() local function check_performance()
vim.api.nvim_exec([=[ vim.api.nvim_exec([=[
func! s:check_performance() abort func! s:check_performance() abort
let s:suggest_faq = ']=]..suggest_faq..[=[' let s:suggest_faq = ']=] .. suggest_faq .. [=['
call health#report_start('Performance') call health#report_start('Performance')
@@ -105,13 +171,13 @@ local function check_performance()
endf endf
call s:check_performance() call s:check_performance()
]=], ]=], false)
false)
end end
-- Load the remote plugin manifest file and check for unregistered plugins -- Load the remote plugin manifest file and check for unregistered plugins
local function check_rplugin_manifest() local function check_rplugin_manifest()
vim.api.nvim_exec([=[ vim.api.nvim_exec(
[=[
func! s:check_rplugin_manifest() abort func! s:check_rplugin_manifest() abort
call health#report_start('Remote Plugins') call health#report_start('Remote Plugins')
let existing_rplugins = {} let existing_rplugins = {}
@@ -172,13 +238,13 @@ local function check_rplugin_manifest()
call s:check_rplugin_manifest() call s:check_rplugin_manifest()
]=], ]=],
false) false
)
end end
local function check_tmux() local function check_tmux()
vim.api.nvim_exec([=[ vim.api.nvim_exec([=[
let s:suggest_faq = ']=]..suggest_faq..[=[' let s:suggest_faq = ']=] .. suggest_faq .. [=['
func! s:get_tmux_option(option) abort func! s:get_tmux_option(option) abort
let cmd = 'tmux show-option -qvg '.a:option " try global scope let cmd = 'tmux show-option -qvg '.a:option " try global scope
@@ -258,7 +324,7 @@ local function check_tmux()
endif endif
" check for RGB capabilities " check for RGB capabilities
let info = system(['tmux', 'server-info']) let info = system(['tmux', 'show-messages', '-JT'])
let has_tc = stridx(info, " Tc: (flag) true") != -1 let has_tc = stridx(info, " Tc: (flag) true") != -1
let has_rgb = stridx(info, " RGB: (flag) true") != -1 let has_rgb = stridx(info, " RGB: (flag) true") != -1
if !has_tc && !has_rgb if !has_tc && !has_rgb
@@ -270,12 +336,12 @@ local function check_tmux()
endf endf
call s:check_tmux() call s:check_tmux()
]=], ]=], false)
false)
end end
local function check_terminal() local function check_terminal()
vim.api.nvim_exec([=[ vim.api.nvim_exec(
[=[
func! s:check_terminal() abort func! s:check_terminal() abort
if !executable('infocmp') if !executable('infocmp')
return return
@@ -307,11 +373,13 @@ local function check_terminal()
call s:check_terminal() call s:check_terminal()
]=], ]=],
false) false
)
end end
function M.check() function M.check()
check_config() check_config()
check_runtime()
check_performance() check_performance()
check_rplugin_manifest() check_rplugin_manifest()
check_terminal() check_terminal()

View File

@@ -20,7 +20,9 @@ function M.check()
local is_loadable, ret = pcall(ts.language.require_language, parsername) local is_loadable, ret = pcall(ts.language.require_language, parsername)
if not is_loadable or not ret then if not is_loadable or not ret then
health.report_error(string.format('Parser "%s" failed to load (path: %s): %s', parsername, parser, ret or '?')) health.report_error(
string.format('Parser "%s" failed to load (path: %s): %s', parsername, parser, ret or '?')
)
elseif ret then elseif ret then
local lang = ts.language.inspect_language(parsername) local lang = ts.language.inspect_language(parsername)
health.report_ok( health.report_ok(

View File

@@ -5,7 +5,7 @@ local Screen = require('test.functional.ui.screen')
local clear = helpers.clear local clear = helpers.clear
local curbuf_contents = helpers.curbuf_contents local curbuf_contents = helpers.curbuf_contents
local command = helpers.command local command = helpers.command
local eq, neq = helpers.eq, helpers.neq local eq, neq, matches = helpers.eq, helpers.neq, helpers.matches
local getcompletion = helpers.funcs.getcompletion local getcompletion = helpers.funcs.getcompletion
describe(':checkhealth', function() describe(':checkhealth', function()
@@ -29,8 +29,7 @@ describe(':checkhealth', function()
-- Do this after startup, otherwise it just breaks $VIMRUNTIME. -- Do this after startup, otherwise it just breaks $VIMRUNTIME.
command("let $VIM='zub'") command("let $VIM='zub'")
command("checkhealth nvim") command("checkhealth nvim")
eq("ERROR: $VIM is invalid: zub", matches('ERROR: $VIM .* zub', curbuf_contents())
string.match(curbuf_contents(), "ERROR: $VIM .* zub"))
end) end)
it('completions can be listed via getcompletion()', function() it('completions can be listed via getcompletion()', function()
clear() clear()