mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge PR #2208 'if_python3 support'
This commit is contained in:
commit
04e098fc3c
@ -1,3 +1,5 @@
|
||||
set -eu
|
||||
|
||||
valgrind_check() {
|
||||
check_logs "$1" "valgrind-*"
|
||||
}
|
||||
@ -7,6 +9,7 @@ asan_check() {
|
||||
}
|
||||
|
||||
check_logs() {
|
||||
local err=""
|
||||
check_core_dumps
|
||||
# Iterate through each log to remove an useless warning
|
||||
for log in $(find "$1" -type f -name "$2"); do
|
||||
@ -48,7 +51,16 @@ check_core_dumps() {
|
||||
}
|
||||
|
||||
setup_deps() {
|
||||
sudo pip install --upgrade pip
|
||||
sudo pip install neovim
|
||||
|
||||
# For pip3
|
||||
# https://github.com/travis-ci/travis-ci/issues/1528
|
||||
# sudo apt-get install -q python3.3-dev
|
||||
# curl -Ss http://python-distribute.org/distribute_setup.py | sudo python3
|
||||
# curl -Ss https://raw.github.com/pypa/pip/master/contrib/get-pip.py | sudo python3
|
||||
# sudo pip3.3 install neovim
|
||||
|
||||
if [ "$BUILD_NVIM_DEPS" != "true" ]; then
|
||||
eval "$(curl -Ss https://raw.githubusercontent.com/neovim/bot-ci/master/scripts/travis-setup.sh) deps-${1}"
|
||||
elif [ "$TRAVIS_OS_NAME" = "linux" ]; then
|
||||
|
@ -1,28 +1,46 @@
|
||||
" The python provider uses a python host to emulate an environment for running
|
||||
" python-vim plugins(:h python-vim). See :h nvim-providers for more
|
||||
" information.
|
||||
" The Python provider uses a Python host to emulate an environment for running
|
||||
" python-vim plugins. See ":help nvim-provider" for more information.
|
||||
"
|
||||
" Associating the plugin with the python host is the first step because plugins
|
||||
" Associating the plugin with the Python host is the first step because plugins
|
||||
" will be passed as command-line arguments
|
||||
if exists('s:loaded_python_provider') || &cp
|
||||
|
||||
if exists('g:loaded_python_provider')
|
||||
finish
|
||||
endif
|
||||
let s:loaded_python_provider = 1
|
||||
let g:loaded_python_provider = 1
|
||||
|
||||
let [s:prog, s:err] = provider#pythonx#Detect(2)
|
||||
if s:prog == ''
|
||||
" Detection failed
|
||||
finish
|
||||
endif
|
||||
|
||||
function! provider#python#Prog()
|
||||
return s:prog
|
||||
endfunction
|
||||
|
||||
function! provider#python#Error()
|
||||
return s:err
|
||||
endfunction
|
||||
|
||||
let s:plugin_path = expand('<sfile>:p:h').'/script_host.py'
|
||||
" The python provider plugin will run in a separate instance of the python
|
||||
|
||||
" The Python provider plugin will run in a separate instance of the Python
|
||||
" host.
|
||||
call remote#host#RegisterClone('legacy-python-provider', 'python')
|
||||
call remote#host#RegisterPlugin('legacy-python-provider', s:plugin_path, [])
|
||||
" Ensure that we can load the python host before bootstrapping
|
||||
try
|
||||
let s:host = remote#host#Require('legacy-python-provider')
|
||||
catch
|
||||
echomsg v:exception
|
||||
finish
|
||||
endtry
|
||||
|
||||
let s:rpcrequest = function('rpcrequest')
|
||||
|
||||
function! provider#python#Call(method, args)
|
||||
if !exists('s:host')
|
||||
let s:rpcrequest = function('rpcrequest')
|
||||
|
||||
" Ensure that we can load the Python host before bootstrapping
|
||||
try
|
||||
let s:host = remote#host#Require('legacy-python-provider')
|
||||
catch
|
||||
echomsg v:exception
|
||||
finish
|
||||
endtry
|
||||
endif
|
||||
return call(s:rpcrequest, insert(insert(a:args, 'python_'.a:method), s:host))
|
||||
endfunction
|
||||
|
47
runtime/autoload/provider/python3.vim
Normal file
47
runtime/autoload/provider/python3.vim
Normal file
@ -0,0 +1,47 @@
|
||||
" The Python3 provider uses a Python3 host to emulate an environment for running
|
||||
" python3 plugins. See ":help nvim-provider" for more information.
|
||||
"
|
||||
" Associating the plugin with the Python3 host is the first step because
|
||||
" plugins will be passed as command-line arguments
|
||||
|
||||
if exists('g:loaded_python3_provider')
|
||||
finish
|
||||
endif
|
||||
let g:loaded_python3_provider = 1
|
||||
|
||||
let [s:prog, s:err] = provider#pythonx#Detect(3)
|
||||
if s:prog == ''
|
||||
" Detection failed
|
||||
finish
|
||||
endif
|
||||
|
||||
function! provider#python3#Prog()
|
||||
return s:prog
|
||||
endfunction
|
||||
|
||||
function! provider#python3#Error()
|
||||
return s:err
|
||||
endfunction
|
||||
|
||||
let s:plugin_path = expand('<sfile>:p:h').'/script_host.py'
|
||||
|
||||
" The Python3 provider plugin will run in a separate instance of the Python3
|
||||
" host.
|
||||
call remote#host#RegisterClone('legacy-python3-provider', 'python3')
|
||||
call remote#host#RegisterPlugin('legacy-python3-provider', s:plugin_path, [])
|
||||
|
||||
function! provider#python3#Call(method, args)
|
||||
if !exists('s:host')
|
||||
let s:rpcrequest = function('rpcrequest')
|
||||
|
||||
" Ensure that we can load the Python3 host before bootstrapping
|
||||
try
|
||||
let s:host = remote#host#Require('legacy-python3-provider')
|
||||
catch
|
||||
echomsg v:exception
|
||||
finish
|
||||
endtry
|
||||
endif
|
||||
|
||||
return call(s:rpcrequest, insert(insert(a:args, 'python_'.a:method), s:host))
|
||||
endfunction
|
69
runtime/autoload/provider/pythonx.vim
Normal file
69
runtime/autoload/provider/pythonx.vim
Normal file
@ -0,0 +1,69 @@
|
||||
" The Python provider helper
|
||||
if exists('s:loaded_pythonx_provider')
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:loaded_pythonx_provider = 1
|
||||
|
||||
function! provider#pythonx#Detect(ver) abort
|
||||
let host_var = (a:ver == 2) ?
|
||||
\ 'g:python_host_prog' : 'g:python3_host_prog'
|
||||
let skip_var = (a:ver == 2) ?
|
||||
\ 'g:python_host_skip_check' : 'g:python3_host_skip_check'
|
||||
let skip = exists(skip_var) ? {skip_var} : 0
|
||||
if exists(host_var)
|
||||
" Disable auto detection
|
||||
let [check, err] = s:check_interpreter({host_var}, a:ver, skip)
|
||||
return check ? [{host_var}, err] : ['', err]
|
||||
endif
|
||||
|
||||
let detect_versions = (a:ver == 2) ?
|
||||
\ ['2.7', '2.6', '2', '']
|
||||
\ : ['3.5', '3.4', '3.3', '3.2', '3', '']
|
||||
|
||||
for prog in map(detect_versions, "'python' . v:val")
|
||||
let [check, err] = s:check_interpreter(prog, a:ver, skip)
|
||||
if check
|
||||
let [check, err] = s:check_version(prog, a:ver, skip)
|
||||
return [prog, err]
|
||||
endif
|
||||
endfor
|
||||
|
||||
" No Python interpreter
|
||||
return ['', 'Neovim module installed Python'
|
||||
\ .a:ver.' interpreter is not found.']
|
||||
endfunction
|
||||
|
||||
function! s:check_version(prog, ver, skip) abort
|
||||
if a:skip
|
||||
return [1, '']
|
||||
endif
|
||||
|
||||
let get_version =
|
||||
\ ' -c "import sys; sys.stdout.write(str(sys.version_info[0]) + '.
|
||||
\ '\".\" + str(sys.version_info[1]))"'
|
||||
let min_version = (a:ver == 2) ? '2.6' : '3.3'
|
||||
if system(a:prog . get_version) >= min_version
|
||||
return [1, '']
|
||||
endif
|
||||
return [0, 'Python ' . get_version . ' interpreter is not supported.']
|
||||
endfunction
|
||||
|
||||
function! s:check_interpreter(prog, ver, skip) abort
|
||||
if !executable(a:prog)
|
||||
return [0, 'Python'.a:ver.' interpreter is not executable.']
|
||||
endif
|
||||
|
||||
if a:skip
|
||||
return [1, '']
|
||||
endif
|
||||
|
||||
" Load neovim module check
|
||||
call system(a:prog . ' -c ' .
|
||||
\ (a:ver == 2 ?
|
||||
\ '''import pkgutil; exit(pkgutil.get_loader("neovim") is None)''':
|
||||
\ '''import importlib; exit(importlib.find_loader("neovim") is None)''')
|
||||
\ )
|
||||
return [!v:shell_error, 'Python'.a:ver.' interpreter have not neovim module.']
|
||||
endfunction
|
||||
|
@ -1,4 +1,4 @@
|
||||
"""Legacy python-vim emulation."""
|
||||
"""Legacy python/python3-vim emulation."""
|
||||
import imp
|
||||
import logging
|
||||
import os
|
||||
@ -35,7 +35,7 @@ class ScriptHost(object):
|
||||
if IS_PYTHON3:
|
||||
self.legacy_vim = self.legacy_vim.with_hook(
|
||||
neovim.DecodeHook(
|
||||
encoding=nvim.options['encoding'].decode('ascii')))
|
||||
encoding=nvim.options['encoding']))
|
||||
sys.modules['vim'] = self.legacy_vim
|
||||
|
||||
def setup(self, nvim):
|
||||
@ -96,7 +96,7 @@ class ScriptHost(object):
|
||||
# Python3 code (exec) must be a string, mixing bytes with
|
||||
# function_def would use bytes.__repr__ instead
|
||||
if isinstance and isinstance(code, bytes):
|
||||
code = code.decode(nvim.options['encoding'].decode('ascii'))
|
||||
code = code.decode(nvim.options['encoding'])
|
||||
# define the function
|
||||
function_def = 'def %s(line, linenr):\n %s' % (fname, code,)
|
||||
exec(function_def, self.module.__dict__)
|
||||
@ -166,6 +166,9 @@ class RedirectStream(object):
|
||||
def writelines(self, seq):
|
||||
self.redirect_handler('\n'.join(seq))
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
|
||||
class LegacyEvalHook(neovim.SessionHook):
|
||||
|
||||
@ -175,8 +178,12 @@ class LegacyEvalHook(neovim.SessionHook):
|
||||
super(LegacyEvalHook, self).__init__(from_nvim=self._string_eval)
|
||||
|
||||
def _string_eval(self, obj, session, method, kind):
|
||||
if method == 'vim_eval' and isinstance(obj, (int, long, float)):
|
||||
return str(obj)
|
||||
if method == 'vim_eval':
|
||||
if IS_PYTHON3:
|
||||
if isinstance(obj, (int, float)):
|
||||
return str(obj)
|
||||
elif isinstance(obj, (int, long, float)):
|
||||
return str(obj)
|
||||
return obj
|
||||
|
||||
|
||||
@ -231,11 +238,11 @@ def discover_runtime_directories(nvim):
|
||||
for path in nvim.list_runtime_paths():
|
||||
if not os.path.exists(path):
|
||||
continue
|
||||
path1 = os.path.join(path, b'pythonx')
|
||||
path1 = os.path.join(path, 'pythonx')
|
||||
if IS_PYTHON3:
|
||||
path2 = os.path.join(path, b'python3')
|
||||
path2 = os.path.join(path, 'python3')
|
||||
else:
|
||||
path2 = os.path.join(path, b'python2')
|
||||
path2 = os.path.join(path, 'python2')
|
||||
if os.path.exists(path1):
|
||||
rv.append(path1)
|
||||
if os.path.exists(path2):
|
||||
|
@ -1,6 +1,7 @@
|
||||
let s:hosts = {}
|
||||
let s:plugin_patterns = {
|
||||
\ 'python': '*.py'
|
||||
\ 'python': '*.py',
|
||||
\ 'python3': '*.py',
|
||||
\ }
|
||||
let s:remote_plugins_manifest = fnamemodify($MYVIMRC, ':p:h')
|
||||
\.'/.'.fnamemodify($MYVIMRC, ':t').'-rplugin~'
|
||||
@ -25,7 +26,12 @@ function! remote#host#RegisterClone(name, orig_name)
|
||||
throw 'No host named "'.a:orig_name.'" is registered'
|
||||
endif
|
||||
let Factory = s:hosts[a:orig_name].factory
|
||||
let s:hosts[a:name] = {'factory': Factory, 'channel': 0, 'initialized': 0}
|
||||
let s:hosts[a:name] = {
|
||||
\ 'factory': Factory,
|
||||
\ 'channel': 0,
|
||||
\ 'initialized': 0,
|
||||
\ 'orig_name': a:orig_name
|
||||
\ }
|
||||
endfunction
|
||||
|
||||
|
||||
@ -51,8 +57,8 @@ function! remote#host#IsRunning(name)
|
||||
endfunction
|
||||
|
||||
|
||||
" Example of registering a python plugin with two commands(one async), one
|
||||
" autocmd(async) and one function(sync):
|
||||
" Example of registering a Python plugin with two commands (one async), one
|
||||
" autocmd (async) and one function (sync):
|
||||
"
|
||||
" let s:plugin_path = expand('<sfile>:p:h').'/nvim_plugin.py'
|
||||
" call remote#host#RegisterPlugin('python', s:plugin_path, [
|
||||
@ -182,72 +188,29 @@ endfunction
|
||||
|
||||
" Registration of standard hosts
|
||||
|
||||
" Python {{{
|
||||
" Python/Python3 {{{
|
||||
function! s:RequirePythonHost(name)
|
||||
let ver_name = has_key(s:hosts[a:name], 'orig_name') ?
|
||||
\ s:hosts[a:name].orig_name : a:name
|
||||
let ver = (ver_name ==# 'python') ? 2 : 3
|
||||
|
||||
" Python host arguments
|
||||
let args = ['-c', 'import neovim; neovim.start_host()']
|
||||
|
||||
" Collect registered python plugins into args
|
||||
" Collect registered Python plugins into args
|
||||
let python_plugins = s:PluginsForHost(a:name)
|
||||
for plugin in python_plugins
|
||||
call add(args, plugin.path)
|
||||
endfor
|
||||
|
||||
" Try loading a python host using `python_host_prog` or `python`
|
||||
let python_host_prog = get(g:, 'python_host_prog', 'python')
|
||||
try
|
||||
let channel_id = rpcstart(python_host_prog, args)
|
||||
if rpcrequest(channel_id, 'poll') == 'ok'
|
||||
return channel_id
|
||||
endif
|
||||
catch
|
||||
endtry
|
||||
|
||||
" Failed, try a little harder to find the correct interpreter or
|
||||
" report a friendly error to user
|
||||
let get_version =
|
||||
\ ' -c "import sys; sys.stdout.write(str(sys.version_info[0]) + '.
|
||||
\ '\".\" + str(sys.version_info[1]))"'
|
||||
|
||||
let supported = ['2.6', '2.7']
|
||||
|
||||
" To load the python host a python executable must be available
|
||||
if exists('g:python_host_prog')
|
||||
\ && executable(g:python_host_prog)
|
||||
\ && index(supported, system(g:python_host_prog.get_version)) >= 0
|
||||
let python_host_prog = g:python_host_prog
|
||||
elseif executable('python')
|
||||
\ && index(supported, system('python'.get_version)) >= 0
|
||||
let python_host_prog = 'python'
|
||||
elseif executable('python2')
|
||||
\ && index(supported, system('python2'.get_version)) >= 0
|
||||
" In some distros, python3 is the default python
|
||||
let python_host_prog = 'python2'
|
||||
else
|
||||
throw 'No python interpreter found.' .
|
||||
\ " Try setting 'let g:python_host_prog=/path/to/python' in your '.nvimrc'" .
|
||||
\ " or see ':help nvim-python'."
|
||||
endif
|
||||
|
||||
" Make sure we pick correct python version on path.
|
||||
let python_host_prog = exepath(python_host_prog)
|
||||
let python_version = systemlist(python_host_prog . ' --version')[0]
|
||||
|
||||
" Execute python, import neovim and print a string. If import_result doesn't
|
||||
" matches the printed string, the user is missing the neovim module
|
||||
let import_result = system(python_host_prog .
|
||||
\ ' -c "import neovim, sys; sys.stdout.write(\"ok\")"')
|
||||
if import_result != 'ok'
|
||||
throw 'No neovim module found for ' . python_version . '.' .
|
||||
\ " Try installing it with 'pip install neovim' or see ':help nvim-python'."
|
||||
endif
|
||||
|
||||
try
|
||||
let channel_id = rpcstart(python_host_prog, args)
|
||||
let channel_id = rpcstart((ver == '2' ?
|
||||
\ provider#python#Prog() : provider#python3#Prog()), args)
|
||||
if rpcrequest(channel_id, 'poll') == 'ok'
|
||||
return channel_id
|
||||
endif
|
||||
catch
|
||||
echomsg v:exception
|
||||
endtry
|
||||
throw 'Failed to load python host. You can try to see what happened ' .
|
||||
\ 'by starting Neovim with $NVIM_PYTHON_PYTHON_LOG and opening '.
|
||||
@ -256,4 +219,5 @@ function! s:RequirePythonHost(name)
|
||||
endfunction
|
||||
|
||||
call remote#host#Register('python', function('s:RequirePythonHost'))
|
||||
call remote#host#Register('python3', function('s:RequirePythonHost'))
|
||||
" }}}
|
||||
|
@ -12,32 +12,72 @@ Python plugins and scripting in Nvim *nvim-python*
|
||||
==============================================================================
|
||||
1. Introduction *nvim-python-intro*
|
||||
|
||||
Through an external Python interpreter connected via |msgpack-rpc|, Nvim
|
||||
offers some support for the legacy |python-vim| interface. For now only the
|
||||
old Vim 7.3 API is supported.
|
||||
Through external Python 2/3 interpreters connected via |msgpack-rpc|, Nvim
|
||||
offers some support for the legacy |python-vim| and |python3| interfaces.
|
||||
|
||||
Note: For now only the old Vim 7.3 API is supported.
|
||||
|
||||
==============================================================================
|
||||
2. Quickstart *nvim-python-quickstart*
|
||||
2. Quickstart *nvim-python-quickstart*
|
||||
|
||||
If you just want to start using Vim Python plugins with Nvim quickly, here's a
|
||||
simple tutorial:
|
||||
To use Vim Python 2/3 plugins with Nvim, do the following:
|
||||
|
||||
- Make sure Python 2.6 or 2.7 is available in your `$PATH`.
|
||||
- Install the `neovim` Python package systemwide:
|
||||
>
|
||||
# pip install neovim
|
||||
- For Python 2 plugins, make sure an interpreter for Python 2.6 or 2.7 is
|
||||
available in your `$PATH`, then install the `neovim` Python package systemwide:
|
||||
>
|
||||
$ sudo pip install neovim
|
||||
<
|
||||
or for the current user:
|
||||
>
|
||||
$ pip install --user neovim
|
||||
<
|
||||
Most Python plugins created for Vim 7.3 should work after these steps.
|
||||
|
||||
- For Python 3 plugins, make sure an interpreter for Python 3.3 or above is
|
||||
available in your `$PATH`, then install the `neovim` Python package systemwide:
|
||||
>
|
||||
$ sudo pip3 install neovim
|
||||
<
|
||||
or for the current user:
|
||||
>
|
||||
$ pip3 install --user neovim
|
||||
<
|
||||
==============================================================================
|
||||
*g:python_host_prog*
|
||||
|
||||
To point Nvim to a specific Python interpreter, set |g:python_host_prog|:
|
||||
To point Nvim to a specific Python 2 interpreter, set |g:python_host_prog|:
|
||||
>
|
||||
let g:python_host_prog='/path/to/python'
|
||||
let g:python_host_prog = '/path/to/python'
|
||||
<
|
||||
*g:python3_host_prog*
|
||||
|
||||
To point Nvim to a specific Python 3 interpreter, set |g:python3_host_prog|:
|
||||
>
|
||||
let g:python3_host_prog = '/path/to/python3'
|
||||
<
|
||||
*g:loaded_python_provider*
|
||||
|
||||
To disable Python 2 interface, set `g:loaded_python_provider` to 1:
|
||||
>
|
||||
let g:loaded_python_provider = 1
|
||||
<
|
||||
*g:loaded_python3_provider*
|
||||
|
||||
To disable Python 3 interface, set `g:loaded_python3_provider` to 0:
|
||||
>
|
||||
let g:loaded_python3_provider = 1
|
||||
<
|
||||
*g:python_host_skip_check*
|
||||
|
||||
To disable Python 2 interpreter check, set `g:python_host_skip_check` to 1:
|
||||
Note: If you disable Python 2 check, you must install neovim module properly.
|
||||
>
|
||||
let g:python_host_skip_check = 1
|
||||
<
|
||||
*g:python3_host_skip_check*
|
||||
|
||||
To disable Python 3 interpreter check, set `g:python3_host_skip_check` to 1:
|
||||
Note: If you disable Python 3 check, you must install neovim module properly.
|
||||
>
|
||||
let g:python3_host_skip_check = 1
|
||||
<
|
||||
==============================================================================
|
||||
vim:tw=78:ts=8:noet:ft=help:norl:
|
||||
|
@ -6577,6 +6577,7 @@ static struct fst {
|
||||
{"prevnonblank", 1, 1, f_prevnonblank},
|
||||
{"printf", 2, 19, f_printf},
|
||||
{"pumvisible", 0, 0, f_pumvisible},
|
||||
{"py3eval", 1, 1, f_py3eval},
|
||||
{"pyeval", 1, 1, f_pyeval},
|
||||
{"range", 1, 3, f_range},
|
||||
{"readfile", 1, 3, f_readfile},
|
||||
@ -11945,6 +11946,14 @@ static void f_pyeval(typval_T *argvars, typval_T *rettv)
|
||||
script_host_eval("python", argvars, rettv);
|
||||
}
|
||||
|
||||
/*
|
||||
* "py3eval()" function
|
||||
*/
|
||||
static void f_py3eval(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
script_host_eval("python3", argvars, rettv);
|
||||
}
|
||||
|
||||
/*
|
||||
* "range()" function
|
||||
*/
|
||||
@ -20458,11 +20467,14 @@ bool eval_has_provider(char *name)
|
||||
} \
|
||||
}
|
||||
|
||||
static int has_clipboard = -1, has_python = -1;
|
||||
static int has_clipboard = -1, has_python = -1, has_python3 = -1;
|
||||
|
||||
if (!strcmp(name, "clipboard")) {
|
||||
check_provider(clipboard);
|
||||
return has_clipboard;
|
||||
} else if (!strcmp(name, "python3")) {
|
||||
check_provider(python3);
|
||||
return has_python3;
|
||||
} else if (!strcmp(name, "python")) {
|
||||
check_provider(python);
|
||||
return has_python;
|
||||
|
@ -1668,22 +1668,22 @@ return {
|
||||
{
|
||||
command='py3',
|
||||
flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
|
||||
func='ex_script_ni',
|
||||
func='ex_python3',
|
||||
},
|
||||
{
|
||||
command='py3do',
|
||||
flags=bit.bor(RANGE, DFLALL, EXTRA, NEEDARG, CMDWIN),
|
||||
func='ex_ni',
|
||||
func='ex_pydo3',
|
||||
},
|
||||
{
|
||||
command='python3',
|
||||
flags=bit.bor(RANGE, EXTRA, NEEDARG, CMDWIN),
|
||||
func='ex_script_ni',
|
||||
func='ex_python3',
|
||||
},
|
||||
{
|
||||
command='py3file',
|
||||
flags=bit.bor(RANGE, FILE1, NEEDARG, CMDWIN),
|
||||
func='ex_ni',
|
||||
func='ex_py3file',
|
||||
},
|
||||
{
|
||||
command='quit',
|
||||
|
@ -797,6 +797,20 @@ void ex_pydo(exarg_T *eap)
|
||||
script_host_do_range("python", eap);
|
||||
}
|
||||
|
||||
void ex_python3(exarg_T *eap)
|
||||
{
|
||||
script_host_execute("python3", eap);
|
||||
}
|
||||
|
||||
void ex_py3file(exarg_T *eap)
|
||||
{
|
||||
script_host_execute_file("python3", eap);
|
||||
}
|
||||
|
||||
void ex_pydo3(exarg_T *eap)
|
||||
{
|
||||
script_host_do_range("python3", eap);
|
||||
}
|
||||
|
||||
/* Command line expansion for :profile. */
|
||||
static enum {
|
||||
|
79
test/functional/runtime/autoload/provider/python3_spec.lua
Normal file
79
test/functional/runtime/autoload/provider/python3_spec.lua
Normal file
@ -0,0 +1,79 @@
|
||||
do
|
||||
local proc =
|
||||
io.popen([[python3 -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
|
||||
if proc:read() ~= 'ok' then
|
||||
-- Don't run these tests if python3 is not available
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local helpers = require('test.functional.helpers')
|
||||
local eval, command, feed = helpers.eval, helpers.command, helpers.feed
|
||||
local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
|
||||
local expect = helpers.expect
|
||||
|
||||
|
||||
describe('python3 commands and functions', function()
|
||||
before_each(function()
|
||||
clear()
|
||||
command('python3 import vim')
|
||||
end)
|
||||
|
||||
it('feature test', function()
|
||||
eq(1, eval('has("python3")'))
|
||||
end)
|
||||
|
||||
it('python3_execute', function()
|
||||
command('python3 vim.vars["set_by_python3"] = [100, 0]')
|
||||
eq({100, 0}, eval('g:set_by_python3'))
|
||||
end)
|
||||
|
||||
it('python3_execute with nested commands', function()
|
||||
command([[python3 vim.command('python3 vim.command("python3 vim.command(\'let set_by_nested_python3 = 555\')")')]])
|
||||
eq(555, eval('g:set_by_nested_python3'))
|
||||
end)
|
||||
|
||||
it('python3_execute with range', function()
|
||||
insert([[
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4]])
|
||||
feed('ggjvj:python3 vim.vars["range"] = vim.current.range[:]<CR>')
|
||||
eq({'line2', 'line3'}, eval('g:range'))
|
||||
end)
|
||||
|
||||
it('py3file', function()
|
||||
local fname = 'py3file.py'
|
||||
local F = io.open(fname, 'w')
|
||||
F:write('vim.command("let set_by_py3file = 123")')
|
||||
F:close()
|
||||
command('py3file py3file.py')
|
||||
eq(123, eval('g:set_by_py3file'))
|
||||
os.remove(fname)
|
||||
end)
|
||||
|
||||
it('py3do', function()
|
||||
-- :pydo3 42 returns None for all lines,
|
||||
-- the buffer should not be changed
|
||||
command('normal :py3do 42')
|
||||
eq(0, eval('&mod'))
|
||||
-- insert some text
|
||||
insert('abc\ndef\nghi')
|
||||
expect([[
|
||||
abc
|
||||
def
|
||||
ghi]])
|
||||
-- go to top and select and replace the first two lines
|
||||
feed('ggvj:py3do return str(linenr)<CR>')
|
||||
expect([[
|
||||
1
|
||||
2
|
||||
ghi]])
|
||||
end)
|
||||
|
||||
it('py3eval', function()
|
||||
eq({1, 2, {['key'] = 'val'}}, eval([[py3eval('[1, 2, {"key": "val"}]')]]))
|
||||
end)
|
||||
end)
|
@ -20,74 +20,60 @@ describe('python commands and functions', function()
|
||||
command('python import vim')
|
||||
end)
|
||||
|
||||
describe('feature test', function()
|
||||
it('ok', function()
|
||||
eq(1, eval('has("python")'))
|
||||
end)
|
||||
it('feature test', function()
|
||||
eq(1, eval('has("python")'))
|
||||
end)
|
||||
|
||||
describe('python_execute', function()
|
||||
it('ok', function()
|
||||
command('python vim.vars["set_by_python"] = [100, 0]')
|
||||
eq({100, 0}, eval('g:set_by_python'))
|
||||
end)
|
||||
it('python_execute', function()
|
||||
command('python vim.vars["set_by_python"] = [100, 0]')
|
||||
eq({100, 0}, eval('g:set_by_python'))
|
||||
end)
|
||||
|
||||
describe('python_execute with nested commands', function()
|
||||
it('ok', function()
|
||||
command([[python vim.command('python vim.command("python vim.command(\'let set_by_nested_python = 555\')")')]])
|
||||
eq(555, eval('g:set_by_nested_python'))
|
||||
end)
|
||||
it('python_execute with nested commands', function()
|
||||
command([[python vim.command('python vim.command("python vim.command(\'let set_by_nested_python = 555\')")')]])
|
||||
eq(555, eval('g:set_by_nested_python'))
|
||||
end)
|
||||
|
||||
describe('python_execute with range', function()
|
||||
it('ok', function()
|
||||
insert([[
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4]])
|
||||
feed('ggjvj:python vim.vars["range"] = vim.current.range[:]<CR>')
|
||||
eq({'line2', 'line3'}, eval('g:range'))
|
||||
end)
|
||||
it('python_execute with range', function()
|
||||
insert([[
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4]])
|
||||
feed('ggjvj:python vim.vars["range"] = vim.current.range[:]<CR>')
|
||||
eq({'line2', 'line3'}, eval('g:range'))
|
||||
end)
|
||||
|
||||
describe('pyfile', function()
|
||||
it('ok', function()
|
||||
local fname = 'pyfile.py'
|
||||
local F = io.open(fname, 'w')
|
||||
F:write('vim.command("let set_by_pyfile = 123")')
|
||||
F:close()
|
||||
command('pyfile pyfile.py')
|
||||
eq(123, eval('g:set_by_pyfile'))
|
||||
os.remove(fname)
|
||||
end)
|
||||
it('pyfile', function()
|
||||
local fname = 'pyfile.py'
|
||||
local F = io.open(fname, 'w')
|
||||
F:write('vim.command("let set_by_pyfile = 123")')
|
||||
F:close()
|
||||
command('pyfile pyfile.py')
|
||||
eq(123, eval('g:set_by_pyfile'))
|
||||
os.remove(fname)
|
||||
end)
|
||||
|
||||
describe('pydo', function()
|
||||
it('ok', function()
|
||||
-- :pydo 42 returns None for all lines,
|
||||
-- the buffer should not be changed
|
||||
command('normal :pydo 42')
|
||||
eq(0, eval('&mod'))
|
||||
-- insert some text
|
||||
insert('abc\ndef\nghi')
|
||||
expect([[
|
||||
abc
|
||||
def
|
||||
ghi]])
|
||||
-- go to top and select and replace the first two lines
|
||||
feed('ggvj:pydo return str(linenr)<CR>')
|
||||
expect([[
|
||||
1
|
||||
2
|
||||
ghi]])
|
||||
end)
|
||||
it('pydo', function()
|
||||
-- :pydo 42 returns None for all lines,
|
||||
-- the buffer should not be changed
|
||||
command('normal :pydo 42')
|
||||
eq(0, eval('&mod'))
|
||||
-- insert some text
|
||||
insert('abc\ndef\nghi')
|
||||
expect([[
|
||||
abc
|
||||
def
|
||||
ghi]])
|
||||
-- go to top and select and replace the first two lines
|
||||
feed('ggvj:pydo return str(linenr)<CR>')
|
||||
expect([[
|
||||
1
|
||||
2
|
||||
ghi]])
|
||||
end)
|
||||
|
||||
describe('pyeval', function()
|
||||
it('ok', function()
|
||||
eq({1, 2, {['key'] = 'val'}}, eval([[pyeval('[1, 2, {"key": "val"}]')]]))
|
||||
end)
|
||||
it('pyeval', function()
|
||||
eq({1, 2, {['key'] = 'val'}}, eval([[pyeval('[1, 2, {"key": "val"}]')]]))
|
||||
end)
|
||||
end)
|
||||
|
Loading…
Reference in New Issue
Block a user