Verified Commit 97fae9dc authored by James McCoy's avatar James McCoy

Merge tag 'v0.3.4' into debian/sid

NVIM v0.3.4
Signed-off-by: James McCoy's avatarJames McCoy <jamessan@debian.org>
parents ad9b34c3 ab2bbbf6
......@@ -112,7 +112,7 @@ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY
# version string, else they are combined with the result of `git describe`.
set(NVIM_VERSION_MAJOR 0)
set(NVIM_VERSION_MINOR 3)
set(NVIM_VERSION_PATCH 3)
set(NVIM_VERSION_PATCH 4)
set(NVIM_VERSION_PRERELEASE "") # for package maintainers
# API level
......
......@@ -258,71 +258,56 @@ function! s:check_python(version) abort
call health#report_start('Python ' . a:version . ' provider (optional)')
let pyname = 'python'.(a:version == 2 ? '' : '3')
let pyenv = resolve(exepath('pyenv'))
let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : ''
let python_exe = ''
let venv = exists('$VIRTUAL_ENV') ? resolve($VIRTUAL_ENV) : ''
let host_prog_var = pyname.'_host_prog'
let loaded_var = 'g:loaded_'.pyname.'_provider'
let python_bin = ''
let python_multiple = []
if exists(loaded_var) && !exists('*provider#'.pyname.'#Call')
call health#report_info('Disabled ('.loaded_var.'='.eval(loaded_var).'). This might be due to some previous error.')
endif
if !empty(pyenv)
if empty(pyenv_root)
call health#report_info(
\ 'pyenv was found, but $PYENV_ROOT is not set. `pyenv root` will be used.'
\ .' If you run into problems, try setting $PYENV_ROOT explicitly.'
\ )
let pyenv_root = s:trim(s:system([pyenv, 'root']))
endif
if !isdirectory(pyenv_root)
call health#report_error('Invalid pyenv root: '.pyenv_root)
else
call health#report_info(printf('pyenv: %s', pyenv))
call health#report_info(printf('pyenv root: %s', pyenv_root))
endif
endif
let [pyenv, pyenv_root] = s:check_for_pyenv()
if exists('g:'.host_prog_var)
call health#report_info(printf('Using: g:%s = "%s"', host_prog_var, get(g:, host_prog_var)))
endif
let [pyname, pythonx_errs] = provider#pythonx#Detect(a:version)
let [pyname, pythonx_errors] = provider#pythonx#Detect(a:version)
if empty(pyname)
call health#report_warn('No Python interpreter was found with the pynvim '
\ . 'module. Using the first available for diagnostics.')
call health#report_warn('No Python executable found that can `import neovim`. '
\ . 'Using the first available executable for diagnostics.')
elseif exists('g:'.host_prog_var)
let python_bin = pyname
let python_exe = pyname
endif
if !empty(pythonx_errs)
call health#report_error('Python provider error', pythonx_errs)
" No Python executable could `import neovim`.
if !empty(pythonx_errors)
call health#report_error('Python provider error:', pythonx_errors)
elseif !empty(pyname) && empty(python_bin)
elseif !empty(pyname) && empty(python_exe)
if !exists('g:'.host_prog_var)
call health#report_info(printf('`g:%s` is not set. Searching for '
\ . '%s in the environment.', host_prog_var, pyname))
endif
if !empty(pyenv)
let python_bin = s:trim(s:system([pyenv, 'which', pyname], '', 1))
let python_exe = s:trim(s:system([pyenv, 'which', pyname], '', 1))
if empty(python_bin)
if empty(python_exe)
call health#report_warn(printf('pyenv could not find %s.', pyname))
endif
endif
if empty(python_bin)
let python_bin = exepath(pyname)
if empty(python_exe)
let python_exe = exepath(pyname)
if exists('$PATH')
for path in split($PATH, has('win32') ? ';' : ':')
let path_bin = s:normalize_path(path.'/'.pyname)
if path_bin != s:normalize_path(python_bin)
if path_bin != s:normalize_path(python_exe)
\ && index(python_multiple, path_bin) == -1
\ && executable(path_bin)
call add(python_multiple, path_bin)
......@@ -336,8 +321,8 @@ function! s:check_python(version) abort
\ . 'Set `g:%s` to avoid surprises.', pyname, host_prog_var))
endif
if python_bin =~# '\<shims\>'
call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_bin), [
if python_exe =~# '\<shims\>'
call health#report_warn(printf('`%s` appears to be a pyenv shim.', python_exe), [
\ '`pyenv` is not in $PATH, your pyenv installation is broken. '
\ .'Set `g:'.host_prog_var.'` to avoid surprises.',
\ ])
......@@ -346,9 +331,9 @@ function! s:check_python(version) abort
endif
endif
if !empty(python_bin) && !exists('g:'.host_prog_var)
if !empty(python_exe) && !exists('g:'.host_prog_var)
if empty(venv) && !empty(pyenv)
\ && !empty(pyenv_root) && resolve(python_bin) !~# '^'.pyenv_root.'/'
\ && !empty(pyenv_root) && resolve(python_exe) !~# '^'.pyenv_root.'/'
call health#report_warn('pyenv is not set up optimally.', [
\ printf('Create a virtualenv specifically '
\ . 'for Neovim using pyenv, and set `g:%s`. This will avoid '
......@@ -362,7 +347,7 @@ function! s:check_python(version) abort
let venv_root = fnamemodify(venv, ':h')
endif
if resolve(python_bin) !~# '^'.venv_root.'/'
if resolve(python_exe) !~# '^'.venv_root.'/'
call health#report_warn('Your virtualenv is not set up optimally.', [
\ printf('Create a virtualenv specifically '
\ . 'for Neovim and use `g:%s`. This will avoid '
......@@ -373,16 +358,16 @@ function! s:check_python(version) abort
endif
endif
if empty(python_bin) && !empty(pyname)
if empty(python_exe) && !empty(pyname)
" An error message should have already printed.
call health#report_error(printf('`%s` was not found.', pyname))
elseif !empty(python_bin) && !s:check_bin(python_bin)
let python_bin = ''
elseif !empty(python_exe) && !s:check_bin(python_exe)
let python_exe = ''
endif
" Check if $VIRTUAL_ENV is valid.
if exists('$VIRTUAL_ENV') && !empty(python_bin)
if $VIRTUAL_ENV ==# matchstr(python_bin, '^\V'.$VIRTUAL_ENV)
if exists('$VIRTUAL_ENV') && !empty(python_exe)
if $VIRTUAL_ENV ==# matchstr(python_exe, '^\V'.$VIRTUAL_ENV)
call health#report_info('$VIRTUAL_ENV matches executable')
else
call health#report_warn(
......@@ -393,7 +378,7 @@ function! s:check_python(version) abort
endif
" Diagnostic output
call health#report_info('Executable: ' . (empty(python_bin) ? 'Not found' : python_bin))
call health#report_info('Executable: ' . (empty(python_exe) ? 'Not found' : python_exe))
if len(python_multiple)
for path_bin in python_multiple
call health#report_info('Other python executable: ' . path_bin)
......@@ -402,29 +387,37 @@ function! s:check_python(version) abort
let pip = 'pip' . (a:version == 2 ? '' : '3')
if !empty(python_bin)
let [pyversion, current, latest, status] = s:version_info(python_bin)
if empty(python_exe)
" No Python executable can import 'neovim'. Check if any Python executable
" can import 'pynvim'. If so, that Python failed to import 'neovim' as
" well, which is most probably due to a failed pip upgrade:
" https://github.com/neovim/neovim/wiki/Following-HEAD#20181118
let [pynvim_exe, errors] = provider#pythonx#DetectByModule('pynvim', a:version)
if !empty(pynvim_exe)
call health#report_error(
\ 'Detected pip upgrade failure: Python executable can import "pynvim" but '
\ . 'not "neovim": '. pynvim_exe,
\ "Use that Python version to reinstall \"pynvim\" and optionally \"neovim\".\n"
\ . pip ." uninstall pynvim neovim\n"
\ . pip ." install pynvim\n"
\ . pip ." install neovim # only if needed by third-party software")
endif
else
let [pyversion, current, latest, status] = s:version_info(python_exe)
if a:version != str2nr(pyversion)
call health#report_warn('Unexpected Python version.' .
\ ' This could lead to confusing error messages.')
endif
if a:version == 3 && str2float(pyversion) < 3.3
call health#report_warn('Python 3.3+ is recommended.')
endif
call health#report_info('Python version: ' . pyversion)
if s:is_bad_response(status)
call health#report_info(printf('pynvim version: %s (%s)', current, status))
let [module_found, _msg] = provider#pythonx#CheckForModule(python_bin,
\ 'pynvim', a:version)
if status !=? '^outdated' && module_found
" neovim module was not found, but pynvim was
call health#report_error('Importing "neovim" failed.',
\ "Reinstall \"pynvim\" and optionally \"neovim\" packages.\n" .
\ pip ." uninstall pynvim neovim\n" .
\ pip ." install pynvim\n" .
\ pip ." install neovim # only if needed by third-party software")
endif
else
call health#report_info(printf('pynvim version: %s', current))
endif
......@@ -444,7 +437,37 @@ function! s:check_python(version) abort
call health#report_ok(printf('Latest pynvim is installed.'))
endif
endif
endfunction
" Check if pyenv is available and a valid pyenv root can be found, then return
" their respective paths. If either of those is invalid, return two empty
" strings, effectivly ignoring pyenv.
function! s:check_for_pyenv() abort
let pyenv_path = resolve(exepath('pyenv'))
if empty(pyenv_path)
return ['', '']
endif
call health#report_info('pyenv: Path: '. pyenv_path)
let pyenv_root = exists('$PYENV_ROOT') ? resolve($PYENV_ROOT) : ''
if empty(pyenv_root)
let pyenv_root = s:trim(s:system([pyenv_path, 'root']))
call health#report_info('pyenv: $PYENV_ROOT is not set. Infer from `pyenv root`.')
endif
if !isdirectory(pyenv_root)
call health#report_warn(
\ printf('pyenv: Root does not exist: %s. '
\ . 'Ignoring pyenv for all following checks.', pyenv_root))
return ['', '']
endif
call health#report_info('pyenv: Root: '.pyenv_root)
return [pyenv_path, pyenv_root]
endfunction
function! s:check_ruby() abort
......
......@@ -21,37 +21,45 @@ function! provider#pythonx#Require(host) abort
return provider#Poll(args, a:host.orig_name, '$NVIM_PYTHON_LOG_FILE')
endfunction
function! provider#pythonx#Detect(major_ver) abort
if a:major_ver == 2
if exists('g:python_host_prog')
return [expand(g:python_host_prog), '']
else
let progs = ['python2', 'python2.7', 'python2.6', 'python']
endif
else
if exists('g:python3_host_prog')
return [expand(g:python3_host_prog), '']
else
let progs = ['python3', 'python3.7', 'python3.6', 'python3.5',
\ 'python3.4', 'python3.3', 'python']
endif
function! s:get_python_executable_from_host_var(major_version) abort
return expand(get(g:, 'python'.(a:major_version == 3 ? '3' : '').'_host_prog', ''))
endfunction
function! s:get_python_candidates(major_version) abort
return {
\ 2: ['python2', 'python2.7', 'python2.6', 'python'],
\ 3: ['python3', 'python3.7', 'python3.6', 'python3.5', 'python3.4', 'python3.3',
\ 'python']
\ }[a:major_version]
endfunction
" Returns [path_to_python_executable, error_message]
function! provider#pythonx#Detect(major_version) abort
return provider#pythonx#DetectByModule('neovim', a:major_version)
endfunction
" Returns [path_to_python_executable, error_message]
function! provider#pythonx#DetectByModule(module, major_version) abort
let python_exe = s:get_python_executable_from_host_var(a:major_version)
if !empty(python_exe)
return [python_exe, '']
endif
let candidates = s:get_python_candidates(a:major_version)
let errors = []
for prog in progs
let [result, err] = provider#pythonx#CheckForModule(prog, 'neovim', a:major_ver)
for exe in candidates
let [result, error] = provider#pythonx#CheckForModule(exe, a:module, a:major_version)
if result
return [prog, err]
return [exe, error]
endif
" Accumulate errors in case we don't find
" any suitable Python interpreter.
call add(errors, err)
" Accumulate errors in case we don't find any suitable Python executable.
call add(errors, error)
endfor
" No suitable Python interpreter found.
return ['', 'provider/pythonx: Could not load Python ' . a:major_ver
\ . ":\n" . join(errors, "\n")]
" No suitable Python executable found.
return ['', 'provider/pythonx: Could not load Python '.a:major_version.":\n".join(errors, "\n")]
endfunction
" Returns array: [prog_exitcode, prog_version]
......
......@@ -22683,6 +22683,16 @@ static void script_host_eval(char *name, typval_T *argvars, typval_T *rettv)
typval_T eval_call_provider(char *provider, char *method, list_T *arguments)
{
if (!eval_has_provider(provider)) {
emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
provider);
return (typval_T){
.v_type = VAR_NUMBER,
.v_lock = VAR_UNLOCKED,
.vval.v_number = (varnumber_T)0
};
}
char func[256];
int name_len = snprintf(func, sizeof(func), "provider#%s#Call", provider);
......
......@@ -3908,12 +3908,7 @@ static void script_host_execute(char *name, exarg_T *eap)
tv_list_append_number(args, (int)eap->line1);
tv_list_append_number(args, (int)eap->line2);
if (!eval_has_provider(name)) {
emsgf("E319: No \"%s\" provider found. Run \":checkhealth provider\"",
name);
} else {
(void)eval_call_provider(name, "execute", args);
}
(void)eval_call_provider(name, "execute", args);
}
}
......
......@@ -11,8 +11,9 @@ do
clear()
if missing_provider('python3') then
it(':python3 reports E319 if provider is missing', function()
expect_err([[Vim%(python3%):E319: No "python3" provider found.*]],
command, 'python3 print("foo")')
local expected = [[Vim%(py3.*%):E319: No "python3" provider found.*]]
expect_err(expected, command, 'py3 print("foo")')
expect_err(expected, command, 'py3file foo')
end)
pending('Python 3 (or the pynvim module) is broken/missing', function() end)
return
......
......@@ -19,8 +19,9 @@ do
clear()
if missing_provider('python') then
it(':python reports E319 if provider is missing', function()
expect_err([[Vim%(python%):E319: No "python" provider found.*]],
command, 'python print("foo")')
local expected = [[Vim%(py.*%):E319: No "python" provider found.*]]
expect_err(expected, command, 'py print("foo")')
expect_err(expected, command, 'pyfile foo')
end)
pending('Python 2 (or the pynvim module) is broken/missing', function() end)
return
......
......@@ -19,8 +19,9 @@ do
clear()
if missing_provider('ruby') then
it(':ruby reports E319 if provider is missing', function()
expect_err([[Vim%(ruby%):E319: No "ruby" provider found.*]],
command, 'ruby puts "foo"')
local expected = [[Vim%(ruby.*%):E319: No "ruby" provider found.*]]
expect_err(expected, command, 'ruby puts "foo"')
expect_err(expected, command, 'rubyfile foo')
end)
pending("Missing neovim RubyGem.", function() end)
return
......
......@@ -163,8 +163,8 @@ set(GPERF_SHA256 588546b945bba4b70b6a3a616e80b4ab466e3f33024a352fc2198112cdbb3ae
set(WINTOOLS_URL https://github.com/neovim/deps/raw/2f9acbecf06365c10baa3c0087f34a54c9c6f949/opt/win32tools.zip)
set(WINTOOLS_SHA256 8bfce7e3a365721a027ce842f2ec1cf878f1726233c215c05964aac07300798c)
set(WINGUI_URL https://github.com/equalsraf/neovim-qt/releases/download/v0.2.11/neovim-qt.zip)
set(WINGUI_SHA256 b7add4b14561a2d8f55d3bbffb1d887209e4f26f837836639c2efeaaed9fa04e)
set(WINGUI_URL https://github.com/equalsraf/neovim-qt/releases/download/v0.2.12/neovim-qt.zip)
set(WINGUI_SHA256 68f8d7d46e21c94ac24577bc65d378c5f622794d11d34950e41edc1b0335560c)
set(WIN32YANK_X86_URL https://github.com/equalsraf/win32yank/releases/download/v0.0.4/win32yank-x86.zip)
set(WIN32YANK_X86_SHA256 62f34e5a46c5d4a7b3f3b512e1ff7b77fedd432f42581cbe825233a996eed62c)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment