mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 8.0.0251: not easy to select Python 2 or 3
Problem: It is not so easy to write a script that works with both Python 2 and Python 3, even when the Python code works with both. Solution: Add 'pyxversion', :pyx, etc. (Marc Weber, Ken Takata)
This commit is contained in:
parent
0c0590d982
commit
f42dd3c390
1
Filelist
1
Filelist
@ -122,6 +122,7 @@ SRC_ALL = \
|
|||||||
src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py \
|
src/testdir/pythonx/topmodule/submodule/subsubmodule/subsubsubmodule.py \
|
||||||
src/testdir/python_after/*.py \
|
src/testdir/python_after/*.py \
|
||||||
src/testdir/python_before/*.py \
|
src/testdir/python_before/*.py \
|
||||||
|
src/testdir/pyxfile/*.py \
|
||||||
src/testdir/bench*.in \
|
src/testdir/bench*.in \
|
||||||
src/testdir/bench*.vim \
|
src/testdir/bench*.vim \
|
||||||
src/testdir/samples/*.txt \
|
src/testdir/samples/*.txt \
|
||||||
|
@ -2239,6 +2239,7 @@ printf({fmt}, {expr1}...) String format text
|
|||||||
pumvisible() Number whether popup menu is visible
|
pumvisible() Number whether popup menu is visible
|
||||||
pyeval({expr}) any evaluate |Python| expression
|
pyeval({expr}) any evaluate |Python| expression
|
||||||
py3eval({expr}) any evaluate |python3| expression
|
py3eval({expr}) any evaluate |python3| expression
|
||||||
|
pyxeval({expr}) any evaluate |python_x| expression
|
||||||
range({expr} [, {max} [, {stride}]])
|
range({expr} [, {max} [, {stride}]])
|
||||||
List items from {expr} to {max}
|
List items from {expr} to {max}
|
||||||
readfile({fname} [, {binary} [, {max}]])
|
readfile({fname} [, {binary} [, {max}]])
|
||||||
@ -6163,6 +6164,14 @@ pyeval({expr}) *pyeval()*
|
|||||||
non-string keys result in error.
|
non-string keys result in error.
|
||||||
{only available when compiled with the |+python| feature}
|
{only available when compiled with the |+python| feature}
|
||||||
|
|
||||||
|
pyxeval({expr}) *pyxeval()*
|
||||||
|
Evaluate Python expression {expr} and return its result
|
||||||
|
converted to Vim data structures.
|
||||||
|
Uses Python 2 or 3, see |python_x| and 'pyxversion'.
|
||||||
|
See also: |pyeval()|, |py3eval()|
|
||||||
|
{only available when compiled with the |+python| or the
|
||||||
|
|+python3| feature}
|
||||||
|
|
||||||
*E726* *E727*
|
*E726* *E727*
|
||||||
range({expr} [, {max} [, {stride}]]) *range()*
|
range({expr} [, {max} [, {stride}]]) *range()*
|
||||||
Returns a |List| with Numbers:
|
Returns a |List| with Numbers:
|
||||||
@ -8402,6 +8411,7 @@ printer Compiled with |:hardcopy| support.
|
|||||||
profile Compiled with |:profile| support.
|
profile Compiled with |:profile| support.
|
||||||
python Compiled with Python 2.x interface. |has-python|
|
python Compiled with Python 2.x interface. |has-python|
|
||||||
python3 Compiled with Python 3.x interface. |has-python|
|
python3 Compiled with Python 3.x interface. |has-python|
|
||||||
|
pythonx Compiled with |python_x| interface. |has-pythonx|
|
||||||
qnx QNX version of Vim.
|
qnx QNX version of Vim.
|
||||||
quickfix Compiled with |quickfix| support.
|
quickfix Compiled with |quickfix| support.
|
||||||
reltime Compiled with |reltime()| support.
|
reltime Compiled with |reltime()| support.
|
||||||
|
@ -16,6 +16,7 @@ The Python Interface to Vim *python* *Python*
|
|||||||
8. pyeval(), py3eval() Vim functions |python-pyeval|
|
8. pyeval(), py3eval() Vim functions |python-pyeval|
|
||||||
9. Dynamic loading |python-dynamic|
|
9. Dynamic loading |python-dynamic|
|
||||||
10. Python 3 |python3|
|
10. Python 3 |python3|
|
||||||
|
11. Python X |python_x|
|
||||||
|
|
||||||
{Vi does not have any of these commands}
|
{Vi does not have any of these commands}
|
||||||
|
|
||||||
@ -711,6 +712,7 @@ vim.Function object *python-Function*
|
|||||||
|
|
||||||
To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()|
|
To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()|
|
||||||
functions to evaluate Python expressions and pass their values to VimL.
|
functions to evaluate Python expressions and pass their values to VimL.
|
||||||
|
|pyxeval()| is also available.
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
9. Dynamic loading *python-dynamic*
|
9. Dynamic loading *python-dynamic*
|
||||||
@ -811,5 +813,69 @@ dynamically, these has() calls will try to load them. If only one can be
|
|||||||
loaded at a time, just checking if Python 2 or 3 are available will prevent
|
loaded at a time, just checking if Python 2 or 3 are available will prevent
|
||||||
the other one from being available.
|
the other one from being available.
|
||||||
|
|
||||||
|
==============================================================================
|
||||||
|
11. Python X *python_x* *pythonx*
|
||||||
|
|
||||||
|
Because most python code can be written so that it works with python 2.6+ and
|
||||||
|
python 3 the pyx* functions and commands have been writen. They work exactly
|
||||||
|
the same as the Python 2 and 3 variants, but select the Python version using
|
||||||
|
the 'pyxversion' setting.
|
||||||
|
|
||||||
|
You should set 'pyxversion' in your |.vimrc| to prefer Python 2 or Python 3
|
||||||
|
for Python commands. If you change this setting at runtime you may risk that
|
||||||
|
state of plugins (such as initialization) may be lost.
|
||||||
|
|
||||||
|
If you want to use a module, you can put it in the {rtp}/pythonx directory.
|
||||||
|
See |pythonx-directory|.
|
||||||
|
|
||||||
|
*:pyx* *:pythonx*
|
||||||
|
The `:pyx` and `:pythonx` commands work similar to `:python`. A simple check
|
||||||
|
if the `:pyx` command is working: >
|
||||||
|
:pyx print("Hello")
|
||||||
|
|
||||||
|
To see what version of Python is being used: >
|
||||||
|
:pyx import sys
|
||||||
|
:pyx print(sys.version)
|
||||||
|
<
|
||||||
|
*:pyxfile* *python_x-special-comments*
|
||||||
|
The `:pyxfile` command works similar to `:pyfile`. However you can add one of
|
||||||
|
these comments to force Vim using `:pyfile` or `:py3file`: >
|
||||||
|
#!/any string/python2 " Shebang. Must be the first line of the file.
|
||||||
|
#!/any string/python3 " Shebang. Must be the first line of the file.
|
||||||
|
# requires python 2.x " Maximum lines depend on 'modelines'.
|
||||||
|
# requires python 3.x " Maximum lines depend on 'modelines'.
|
||||||
|
Unlike normal modelines, the bottom of the file is not checked.
|
||||||
|
If none of them are found, the 'pyxversion' setting is used.
|
||||||
|
*W20* *W21*
|
||||||
|
If Vim does not support the selected Python version a silent message will be
|
||||||
|
printed. Use `:messages` to read them.
|
||||||
|
|
||||||
|
*:pyxdo*
|
||||||
|
The `:pyxdo` command works similar to `:pydo`.
|
||||||
|
|
||||||
|
*has-pythonx*
|
||||||
|
You can test if pyx* commands are available with: >
|
||||||
|
if has('pythonx')
|
||||||
|
echo 'pyx* commands are available. (Python ' . &pyx . ')'
|
||||||
|
endif
|
||||||
|
|
||||||
|
When compiled with only one of |+python| or |+python3|, the has() returns 1.
|
||||||
|
When compiled with both |+python| and |+python3|, the test depends on the
|
||||||
|
'pyxversion' setting. If 'pyxversion' is 0, it tests Python 3 first, and if
|
||||||
|
it is not available then Python 2. If 'pyxversion' is 2 or 3, it tests only
|
||||||
|
Python 2 or 3 respectively.
|
||||||
|
|
||||||
|
Note that for has('pythonx') to work it may try to dynamically load Python 3
|
||||||
|
or 2. This may have side effects, especially when Vim can only load one of
|
||||||
|
the two.
|
||||||
|
|
||||||
|
If a user prefers Python 2 and want to fallback to Python 3, he needs to set
|
||||||
|
'pyxversion' explicitly in his |.vimrc|. E.g.: >
|
||||||
|
if has('python')
|
||||||
|
set pyx=2
|
||||||
|
elseif has('python3')
|
||||||
|
set pyx=3
|
||||||
|
endif
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
vim:tw=78:ts=8:ft=help:norl:
|
vim:tw=78:ts=8:ft=help:norl:
|
||||||
|
@ -1440,6 +1440,10 @@ tag command action ~
|
|||||||
|:python| :py[thon] execute Python command
|
|:python| :py[thon] execute Python command
|
||||||
|:pydo| :pyd[o] execute Python command for each line
|
|:pydo| :pyd[o] execute Python command for each line
|
||||||
|:pyfile| :pyf[ile] execute Python script file
|
|:pyfile| :pyf[ile] execute Python script file
|
||||||
|
|:pyx| :pyx execute |python_x| command
|
||||||
|
|:pythonx| :pythonx same as :pyx
|
||||||
|
|:pyxdo| :pyxd[o] execute |python_x| command for each line
|
||||||
|
|:pyxfile| :pyxf[ile] execute |python_x| script file
|
||||||
|:quit| :q[uit] quit current window (when one window quit Vim)
|
|:quit| :q[uit] quit current window (when one window quit Vim)
|
||||||
|:quitall| :quita[ll] quit Vim
|
|:quitall| :quita[ll] quit Vim
|
||||||
|:qall| :qa[ll] quit Vim
|
|:qall| :qa[ll] quit Vim
|
||||||
|
@ -5786,6 +5786,34 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
Specifies the name of the Python 3 shared library. The default is
|
Specifies the name of the Python 3 shared library. The default is
|
||||||
DYNAMIC_PYTHON3_DLL, which was specified at compile time.
|
DYNAMIC_PYTHON3_DLL, which was specified at compile time.
|
||||||
Environment variables are expanded |:set_env|.
|
Environment variables are expanded |:set_env|.
|
||||||
|
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||||
|
security reasons.
|
||||||
|
|
||||||
|
*'pyxversion'* *'pyx'*
|
||||||
|
'pyxversion' 'pyx' number (default depends on the build)
|
||||||
|
global
|
||||||
|
{not in Vi}
|
||||||
|
{only available when compiled with the |+python| or
|
||||||
|
the |+python3| feature}
|
||||||
|
Specifies the python version used for pyx* functions and commands
|
||||||
|
|python_x|. The default value is as follows:
|
||||||
|
|
||||||
|
Compiled with Default ~
|
||||||
|
|+python| and |+python3| 0
|
||||||
|
only |+python| 2
|
||||||
|
only |+python3| 3
|
||||||
|
|
||||||
|
Available values are 0, 2 and 3.
|
||||||
|
If 'pyxversion' is 0, it is set to 2 or 3 after the first execution of
|
||||||
|
any python2/3 commands or functions. E.g. `:py` sets to 2, and `:py3`
|
||||||
|
sets to 3. `:pyx` sets it to 3 if Python 3 is available, otherwise sets
|
||||||
|
to 2 if Python 2 is available.
|
||||||
|
See also: |has-pythonx|
|
||||||
|
|
||||||
|
If Vim is compiled with only |+python| or |+python3| setting
|
||||||
|
'pyxversion' has no effect. The pyx* functions and commands are
|
||||||
|
always the same as the compiled version.
|
||||||
|
|
||||||
This option cannot be set from a |modeline| or in the |sandbox|, for
|
This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||||
security reasons.
|
security reasons.
|
||||||
|
|
||||||
|
@ -835,6 +835,7 @@ Short explanation of each option: *option-list*
|
|||||||
'pumheight' 'ph' maximum height of the popup menu
|
'pumheight' 'ph' maximum height of the popup menu
|
||||||
'pythondll' name of the Python 2 dynamic library
|
'pythondll' name of the Python 2 dynamic library
|
||||||
'pythonthreedll' name of the Python 3 dynamic library
|
'pythonthreedll' name of the Python 3 dynamic library
|
||||||
|
'pyxversion' 'pyx' Python version used for pyx* commands
|
||||||
'quoteescape' 'qe' escape characters used in a string
|
'quoteescape' 'qe' escape characters used in a string
|
||||||
'readonly' 'ro' disallow writing the buffer
|
'readonly' 'ro' disallow writing the buffer
|
||||||
'redrawtime' 'rdt' timeout for 'hlsearch' and |:match| highlighting
|
'redrawtime' 'rdt' timeout for 'hlsearch' and |:match| highlighting
|
||||||
|
@ -923,7 +923,7 @@ if has("folding")
|
|||||||
call append("$", "foldmarker\tmarkers used when 'foldmethod' is \"marker\"")
|
call append("$", "foldmarker\tmarkers used when 'foldmethod' is \"marker\"")
|
||||||
call append("$", "\t(local to window)")
|
call append("$", "\t(local to window)")
|
||||||
call <SID>OptionL("fmr")
|
call <SID>OptionL("fmr")
|
||||||
call append("$", "foldnestmax\tmaximum fold depth for when 'foldmethod is \"indent\" or \"syntax\"")
|
call append("$", "foldnestmax\tmaximum fold depth for when 'foldmethod' is \"indent\" or \"syntax\"")
|
||||||
call append("$", "\t(local to window)")
|
call append("$", "\t(local to window)")
|
||||||
call <SID>OptionL("fdn")
|
call <SID>OptionL("fdn")
|
||||||
endif
|
endif
|
||||||
@ -1324,6 +1324,10 @@ if exists("&perldll")
|
|||||||
call append("$", "perldll\tname of the Perl dynamic library")
|
call append("$", "perldll\tname of the Perl dynamic library")
|
||||||
call <SID>OptionG("perldll", &perldll)
|
call <SID>OptionG("perldll", &perldll)
|
||||||
endif
|
endif
|
||||||
|
if has('pythonx')
|
||||||
|
call append("$", "pyxversion\twhether to use Python 2 or 3")
|
||||||
|
call append("$", " \tset pyx=" . &wd)
|
||||||
|
endif
|
||||||
if exists("&pythondll")
|
if exists("&pythondll")
|
||||||
call append("$", "pythondll\tname of the Python 2 dynamic library")
|
call append("$", "pythondll\tname of the Python 2 dynamic library")
|
||||||
call <SID>OptionG("pythondll", &pythondll)
|
call <SID>OptionG("pythondll", &pythondll)
|
||||||
|
@ -2151,6 +2151,8 @@ test_arglist \
|
|||||||
test_popup \
|
test_popup \
|
||||||
test_profile \
|
test_profile \
|
||||||
test_put \
|
test_put \
|
||||||
|
test_pyx2 \
|
||||||
|
test_pyx3 \
|
||||||
test_quickfix \
|
test_quickfix \
|
||||||
test_regexp_latin \
|
test_regexp_latin \
|
||||||
test_regexp_utf8 \
|
test_regexp_utf8 \
|
||||||
@ -2754,6 +2756,7 @@ shadow: runtime pixmaps
|
|||||||
../../testdir/*.vim \
|
../../testdir/*.vim \
|
||||||
../../testdir/*.py \
|
../../testdir/*.py \
|
||||||
../../testdir/python* \
|
../../testdir/python* \
|
||||||
|
../../testdir/pyxfile \
|
||||||
../../testdir/sautest \
|
../../testdir/sautest \
|
||||||
../../testdir/samples \
|
../../testdir/samples \
|
||||||
../../testdir/test83-tags? \
|
../../testdir/test83-tags? \
|
||||||
|
@ -289,6 +289,9 @@ static void f_py3eval(typval_T *argvars, typval_T *rettv);
|
|||||||
#ifdef FEAT_PYTHON
|
#ifdef FEAT_PYTHON
|
||||||
static void f_pyeval(typval_T *argvars, typval_T *rettv);
|
static void f_pyeval(typval_T *argvars, typval_T *rettv);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
static void f_pyxeval(typval_T *argvars, typval_T *rettv);
|
||||||
|
#endif
|
||||||
static void f_range(typval_T *argvars, typval_T *rettv);
|
static void f_range(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_readfile(typval_T *argvars, typval_T *rettv);
|
static void f_readfile(typval_T *argvars, typval_T *rettv);
|
||||||
static void f_reltime(typval_T *argvars, typval_T *rettv);
|
static void f_reltime(typval_T *argvars, typval_T *rettv);
|
||||||
@ -715,6 +718,9 @@ static struct fst
|
|||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_PYTHON
|
#ifdef FEAT_PYTHON
|
||||||
{"pyeval", 1, 1, f_pyeval},
|
{"pyeval", 1, 1, f_pyeval},
|
||||||
|
#endif
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
{"pyxeval", 1, 1, f_pyxeval},
|
||||||
#endif
|
#endif
|
||||||
{"range", 1, 3, f_range},
|
{"range", 1, 3, f_range},
|
||||||
{"readfile", 1, 3, f_readfile},
|
{"readfile", 1, 3, f_readfile},
|
||||||
@ -5734,15 +5740,13 @@ f_has(typval_T *argvars, typval_T *rettv)
|
|||||||
#ifdef FEAT_PERSISTENT_UNDO
|
#ifdef FEAT_PERSISTENT_UNDO
|
||||||
"persistent_undo",
|
"persistent_undo",
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_PYTHON
|
#if defined(FEAT_PYTHON) && !defined(DYNAMIC_PYTHON)
|
||||||
#ifndef DYNAMIC_PYTHON
|
|
||||||
"python",
|
"python",
|
||||||
|
"pythonx",
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#if defined(FEAT_PYTHON3) && !defined(DYNAMIC_PYTHON3)
|
||||||
#ifdef FEAT_PYTHON3
|
|
||||||
#ifndef DYNAMIC_PYTHON3
|
|
||||||
"python3",
|
"python3",
|
||||||
#endif
|
"pythonx",
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_POSTSCRIPT
|
#ifdef FEAT_POSTSCRIPT
|
||||||
"postscript",
|
"postscript",
|
||||||
@ -5972,17 +5976,30 @@ f_has(typval_T *argvars, typval_T *rettv)
|
|||||||
else if (STRICMP(name, "ruby") == 0)
|
else if (STRICMP(name, "ruby") == 0)
|
||||||
n = ruby_enabled(FALSE);
|
n = ruby_enabled(FALSE);
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_PYTHON
|
|
||||||
#ifdef DYNAMIC_PYTHON
|
#ifdef DYNAMIC_PYTHON
|
||||||
else if (STRICMP(name, "python") == 0)
|
else if (STRICMP(name, "python") == 0)
|
||||||
n = python_enabled(FALSE);
|
n = python_enabled(FALSE);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
#ifdef FEAT_PYTHON3
|
|
||||||
#ifdef DYNAMIC_PYTHON3
|
#ifdef DYNAMIC_PYTHON3
|
||||||
else if (STRICMP(name, "python3") == 0)
|
else if (STRICMP(name, "python3") == 0)
|
||||||
n = python3_enabled(FALSE);
|
n = python3_enabled(FALSE);
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(DYNAMIC_PYTHON) || defined(DYNAMIC_PYTHON3)
|
||||||
|
else if (STRICMP(name, "pythonx") == 0)
|
||||||
|
{
|
||||||
|
# if defined(DYNAMIC_PYTHON) && defined(DYNAMIC_PYTHON3)
|
||||||
|
if (p_pyx == 0)
|
||||||
|
n = python3_enabled(FALSE) || python_enabled(FALSE);
|
||||||
|
else if (p_pyx == 3)
|
||||||
|
n = python3_enabled(FALSE);
|
||||||
|
else if (p_pyx == 2)
|
||||||
|
n = python_enabled(FALSE);
|
||||||
|
# elif defined(DYNAMIC_PYTHON)
|
||||||
|
n = python_enabled(FALSE);
|
||||||
|
# elif defined(DYNAMIC_PYTHON3)
|
||||||
|
n = python3_enabled(FALSE);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DYNAMIC_PERL
|
#ifdef DYNAMIC_PERL
|
||||||
else if (STRICMP(name, "perl") == 0)
|
else if (STRICMP(name, "perl") == 0)
|
||||||
@ -8007,6 +8024,9 @@ f_py3eval(typval_T *argvars, typval_T *rettv)
|
|||||||
char_u *str;
|
char_u *str;
|
||||||
char_u buf[NUMBUFLEN];
|
char_u buf[NUMBUFLEN];
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 3;
|
||||||
|
|
||||||
str = get_tv_string_buf(&argvars[0], buf);
|
str = get_tv_string_buf(&argvars[0], buf);
|
||||||
do_py3eval(str, rettv);
|
do_py3eval(str, rettv);
|
||||||
}
|
}
|
||||||
@ -8022,11 +8042,35 @@ f_pyeval(typval_T *argvars, typval_T *rettv)
|
|||||||
char_u *str;
|
char_u *str;
|
||||||
char_u buf[NUMBUFLEN];
|
char_u buf[NUMBUFLEN];
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 2;
|
||||||
|
|
||||||
str = get_tv_string_buf(&argvars[0], buf);
|
str = get_tv_string_buf(&argvars[0], buf);
|
||||||
do_pyeval(str, rettv);
|
do_pyeval(str, rettv);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
/*
|
||||||
|
* "pyxeval()" function
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
f_pyxeval(typval_T *argvars, typval_T *rettv)
|
||||||
|
{
|
||||||
|
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
init_pyxversion();
|
||||||
|
if (p_pyx == 2)
|
||||||
|
f_pyeval(argvars, rettv);
|
||||||
|
else
|
||||||
|
f_py3eval(argvars, rettv);
|
||||||
|
# elif defined(FEAT_PYTHON)
|
||||||
|
f_pyeval(argvars, rettv);
|
||||||
|
# elif defined(FEAT_PYTHON3)
|
||||||
|
f_py3eval(argvars, rettv);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "range()" function
|
* "range()" function
|
||||||
*/
|
*/
|
||||||
|
@ -1132,6 +1132,18 @@ EX(CMD_python3, "python3", ex_py3,
|
|||||||
EX(CMD_py3file, "py3file", ex_py3file,
|
EX(CMD_py3file, "py3file", ex_py3file,
|
||||||
RANGE|FILE1|NEEDARG|CMDWIN,
|
RANGE|FILE1|NEEDARG|CMDWIN,
|
||||||
ADDR_LINES),
|
ADDR_LINES),
|
||||||
|
EX(CMD_pyx, "pyx", ex_pyx,
|
||||||
|
RANGE|EXTRA|NEEDARG|CMDWIN,
|
||||||
|
ADDR_LINES),
|
||||||
|
EX(CMD_pyxdo, "pyxdo", ex_pyxdo,
|
||||||
|
RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN,
|
||||||
|
ADDR_LINES),
|
||||||
|
EX(CMD_pythonx, "pythonx", ex_pyx,
|
||||||
|
RANGE|EXTRA|NEEDARG|CMDWIN,
|
||||||
|
ADDR_LINES),
|
||||||
|
EX(CMD_pyxfile, "pyxfile", ex_pyxfile,
|
||||||
|
RANGE|FILE1|NEEDARG|CMDWIN,
|
||||||
|
ADDR_LINES),
|
||||||
EX(CMD_quit, "quit", ex_quit,
|
EX(CMD_quit, "quit", ex_quit,
|
||||||
BANG|RANGE|COUNT|NOTADR|TRLBAR|CMDWIN,
|
BANG|RANGE|COUNT|NOTADR|TRLBAR|CMDWIN,
|
||||||
ADDR_WINDOWS),
|
ADDR_WINDOWS),
|
||||||
|
188
src/ex_cmds2.c
188
src/ex_cmds2.c
@ -3675,6 +3675,194 @@ ex_options(
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_PYTHON3) || defined(FEAT_PYTHON) || defined(PROTO)
|
||||||
|
|
||||||
|
# if (defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)) || defined(PROTO)
|
||||||
|
/*
|
||||||
|
* Detect Python 3 or 2, and initialize 'pyxversion'.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
init_pyxversion(void)
|
||||||
|
{
|
||||||
|
if (p_pyx == 0)
|
||||||
|
{
|
||||||
|
if (python3_enabled(FALSE))
|
||||||
|
p_pyx = 3;
|
||||||
|
else if (python_enabled(FALSE))
|
||||||
|
p_pyx = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Does a file contain one of the following strings at the beginning of any
|
||||||
|
* line?
|
||||||
|
* "#!(any string)python2" => returns 2
|
||||||
|
* "#!(any string)python3" => returns 3
|
||||||
|
* "# requires python 2.x" => returns 2
|
||||||
|
* "# requires python 3.x" => returns 3
|
||||||
|
* otherwise return 0.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
requires_py_version(char_u *filename)
|
||||||
|
{
|
||||||
|
FILE *file;
|
||||||
|
int requires_py_version = 0;
|
||||||
|
int i, lines;
|
||||||
|
|
||||||
|
lines = (int)p_mls;
|
||||||
|
if (lines < 0)
|
||||||
|
lines = 5;
|
||||||
|
|
||||||
|
file = mch_fopen((char *)filename, "r");
|
||||||
|
if (file != NULL)
|
||||||
|
{
|
||||||
|
for (i = 0; i < lines; i++)
|
||||||
|
{
|
||||||
|
if (vim_fgets(IObuff, IOSIZE, file))
|
||||||
|
break;
|
||||||
|
if (i == 0 && IObuff[0] == '#' && IObuff[1] == '!')
|
||||||
|
{
|
||||||
|
/* Check shebang. */
|
||||||
|
if (strstr((char *)IObuff + 2, "python2") != NULL)
|
||||||
|
{
|
||||||
|
requires_py_version = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (strstr((char *)IObuff + 2, "python3") != NULL)
|
||||||
|
{
|
||||||
|
requires_py_version = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IObuff[21] = '\0';
|
||||||
|
if (STRCMP("# requires python 2.x", IObuff) == 0)
|
||||||
|
{
|
||||||
|
requires_py_version = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (STRCMP("# requires python 3.x", IObuff) == 0)
|
||||||
|
{
|
||||||
|
requires_py_version = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
}
|
||||||
|
return requires_py_version;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source a python file using the requested python version.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
source_pyx_file(exarg_T *eap, char_u *fname)
|
||||||
|
{
|
||||||
|
exarg_T ex;
|
||||||
|
int v = requires_py_version(fname);
|
||||||
|
|
||||||
|
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
init_pyxversion();
|
||||||
|
# endif
|
||||||
|
if (v == 0)
|
||||||
|
{
|
||||||
|
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
/* user didn't choose a preference, 'pyx' is used */
|
||||||
|
v = p_pyx;
|
||||||
|
# elif defined(FEAT_PYTHON)
|
||||||
|
v = 2;
|
||||||
|
# elif defined(FEAT_PYTHON3)
|
||||||
|
v = 3;
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now source, if required python version is not supported show
|
||||||
|
* unobtrusive message.
|
||||||
|
*/
|
||||||
|
if (eap == NULL)
|
||||||
|
vim_memset(&ex, 0, sizeof(ex));
|
||||||
|
else
|
||||||
|
ex = *eap;
|
||||||
|
ex.arg = fname;
|
||||||
|
ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
|
||||||
|
|
||||||
|
if (v == 2)
|
||||||
|
{
|
||||||
|
# ifdef FEAT_PYTHON
|
||||||
|
ex_pyfile(&ex);
|
||||||
|
# else
|
||||||
|
vim_snprintf((char *)IObuff, IOSIZE,
|
||||||
|
_("W20: Required python version 2.x not supported, ignoring file: %s"),
|
||||||
|
fname);
|
||||||
|
MSG(IObuff);
|
||||||
|
# endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
# ifdef FEAT_PYTHON3
|
||||||
|
ex_py3file(&ex);
|
||||||
|
# else
|
||||||
|
vim_snprintf((char *)IObuff, IOSIZE,
|
||||||
|
_("W21: Required python version 3.x not supported, ignoring file: %s"),
|
||||||
|
fname);
|
||||||
|
MSG(IObuff);
|
||||||
|
# endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ":pyxfile {fname}"
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ex_pyxfile(exarg_T *eap)
|
||||||
|
{
|
||||||
|
source_pyx_file(eap, eap->arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ":pyx"
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ex_pyx(exarg_T *eap)
|
||||||
|
{
|
||||||
|
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
init_pyxversion();
|
||||||
|
if (p_pyx == 2)
|
||||||
|
ex_python(eap);
|
||||||
|
else
|
||||||
|
ex_py3(eap);
|
||||||
|
# elif defined(FEAT_PYTHON)
|
||||||
|
ex_python(eap);
|
||||||
|
# elif defined(FEAT_PYTHON3)
|
||||||
|
ex_py3(eap);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ":pyxdo"
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ex_pyxdo(exarg_T *eap)
|
||||||
|
{
|
||||||
|
# if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
init_pyxversion();
|
||||||
|
if (p_pyx == 2)
|
||||||
|
ex_pydo(eap);
|
||||||
|
else
|
||||||
|
ex_py3do(eap);
|
||||||
|
# elif defined(FEAT_PYTHON)
|
||||||
|
ex_pydo(eap);
|
||||||
|
# elif defined(FEAT_PYTHON3)
|
||||||
|
ex_py3do(eap);
|
||||||
|
# endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ":source {fname}"
|
* ":source {fname}"
|
||||||
*/
|
*/
|
||||||
|
@ -288,6 +288,11 @@ static void ex_popup(exarg_T *eap);
|
|||||||
# define ex_py3do ex_ni
|
# define ex_py3do ex_ni
|
||||||
# define ex_py3file ex_ni
|
# define ex_py3file ex_ni
|
||||||
#endif
|
#endif
|
||||||
|
#if !defined(FEAT_PYTHON) && !defined(FEAT_PYTHON3)
|
||||||
|
# define ex_pyx ex_script_ni
|
||||||
|
# define ex_pyxdo ex_ni
|
||||||
|
# define ex_pyxfile ex_ni
|
||||||
|
#endif
|
||||||
#ifndef FEAT_TCL
|
#ifndef FEAT_TCL
|
||||||
# define ex_tcl ex_script_ni
|
# define ex_tcl ex_script_ni
|
||||||
# define ex_tcldo ex_ni
|
# define ex_tcldo ex_ni
|
||||||
|
@ -1114,6 +1114,9 @@ ex_python(exarg_T *eap)
|
|||||||
{
|
{
|
||||||
char_u *script;
|
char_u *script;
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 2;
|
||||||
|
|
||||||
script = script_get(eap, eap->arg);
|
script = script_get(eap, eap->arg);
|
||||||
if (!eap->skip)
|
if (!eap->skip)
|
||||||
{
|
{
|
||||||
@ -1137,6 +1140,9 @@ ex_pyfile(exarg_T *eap)
|
|||||||
const char *file = (char *)eap->arg;
|
const char *file = (char *)eap->arg;
|
||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 2;
|
||||||
|
|
||||||
/* Have to do it like this. PyRun_SimpleFile requires you to pass a
|
/* Have to do it like this. PyRun_SimpleFile requires you to pass a
|
||||||
* stdio file pointer, but Vim and the Python DLL are compiled with
|
* stdio file pointer, but Vim and the Python DLL are compiled with
|
||||||
* different options under Windows, meaning that stdio pointers aren't
|
* different options under Windows, meaning that stdio pointers aren't
|
||||||
@ -1175,6 +1181,9 @@ ex_pyfile(exarg_T *eap)
|
|||||||
void
|
void
|
||||||
ex_pydo(exarg_T *eap)
|
ex_pydo(exarg_T *eap)
|
||||||
{
|
{
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 2;
|
||||||
|
|
||||||
DoPyCommand((char *)eap->arg,
|
DoPyCommand((char *)eap->arg,
|
||||||
(rangeinitializer) init_range_cmd,
|
(rangeinitializer) init_range_cmd,
|
||||||
(runner)run_do,
|
(runner)run_do,
|
||||||
|
@ -1004,6 +1004,9 @@ ex_py3(exarg_T *eap)
|
|||||||
{
|
{
|
||||||
char_u *script;
|
char_u *script;
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 3;
|
||||||
|
|
||||||
script = script_get(eap, eap->arg);
|
script = script_get(eap, eap->arg);
|
||||||
if (!eap->skip)
|
if (!eap->skip)
|
||||||
{
|
{
|
||||||
@ -1028,6 +1031,9 @@ ex_py3file(exarg_T *eap)
|
|||||||
char *p;
|
char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 3;
|
||||||
|
|
||||||
/* Have to do it like this. PyRun_SimpleFile requires you to pass a
|
/* Have to do it like this. PyRun_SimpleFile requires you to pass a
|
||||||
* stdio file pointer, but Vim and the Python DLL are compiled with
|
* stdio file pointer, but Vim and the Python DLL are compiled with
|
||||||
* different options under Windows, meaning that stdio pointers aren't
|
* different options under Windows, meaning that stdio pointers aren't
|
||||||
@ -1080,6 +1086,9 @@ ex_py3file(exarg_T *eap)
|
|||||||
void
|
void
|
||||||
ex_py3do(exarg_T *eap)
|
ex_py3do(exarg_T *eap)
|
||||||
{
|
{
|
||||||
|
if (p_pyx == 0)
|
||||||
|
p_pyx = 3;
|
||||||
|
|
||||||
DoPyCommand((char *)eap->arg,
|
DoPyCommand((char *)eap->arg,
|
||||||
(rangeinitializer)init_range_cmd,
|
(rangeinitializer)init_range_cmd,
|
||||||
(runner)run_do,
|
(runner)run_do,
|
||||||
|
28
src/option.c
28
src/option.c
@ -479,6 +479,17 @@ struct vimoption
|
|||||||
# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
|
# define HIGHLIGHT_INIT "8:SpecialKey,@:NonText,d:Directory,e:ErrorMsg,i:IncSearch,l:Search,m:MoreMsg,M:ModeMsg,n:LineNr,N:CursorLineNr,r:Question,s:StatusLine,S:StatusLineNC,t:Title,v:Visual,w:WarningMsg,W:WildMenu,>:SignColumn,*:TabLine,#:TabLineSel,_:TabLineFill"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Default python version for pyx* commands */
|
||||||
|
#if defined(FEAT_PYTHON) && defined(FEAT_PYTHON3)
|
||||||
|
# define DEFAULT_PYTHON_VER 0
|
||||||
|
#elif defined(FEAT_PYTHON3)
|
||||||
|
# define DEFAULT_PYTHON_VER 3
|
||||||
|
#elif defined(FEAT_PYTHON)
|
||||||
|
# define DEFAULT_PYTHON_VER 2
|
||||||
|
#else
|
||||||
|
# define DEFAULT_PYTHON_VER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* options[] is initialized here.
|
* options[] is initialized here.
|
||||||
* The order of the options MUST be alphabetic for ":set all" and findoption().
|
* The order of the options MUST be alphabetic for ":set all" and findoption().
|
||||||
@ -2143,6 +2154,14 @@ static struct vimoption options[] =
|
|||||||
{(char_u *)DYNAMIC_PYTHON_DLL, (char_u *)0L}
|
{(char_u *)DYNAMIC_PYTHON_DLL, (char_u *)0L}
|
||||||
SCRIPTID_INIT},
|
SCRIPTID_INIT},
|
||||||
#endif
|
#endif
|
||||||
|
{"pyxversion", "pyx", P_NUM|P_VI_DEF|P_SECURE,
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
(char_u *)&p_pyx, PV_NONE,
|
||||||
|
#else
|
||||||
|
(char_u *)NULL, PV_NONE,
|
||||||
|
#endif
|
||||||
|
{(char_u *)DEFAULT_PYTHON_VER, (char_u *)0L}
|
||||||
|
SCRIPTID_INIT},
|
||||||
{"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF,
|
{"quoteescape", "qe", P_STRING|P_ALLOCED|P_VI_DEF,
|
||||||
#ifdef FEAT_TEXTOBJ
|
#ifdef FEAT_TEXTOBJ
|
||||||
(char_u *)&p_qe, PV_QE,
|
(char_u *)&p_qe, PV_QE,
|
||||||
@ -8826,6 +8845,15 @@ set_num_option(
|
|||||||
mzvim_reset_timer();
|
mzvim_reset_timer();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
/* 'pyxversion' */
|
||||||
|
else if (pp == &p_pyx)
|
||||||
|
{
|
||||||
|
if (p_pyx != 0 && p_pyx != 2 && p_pyx != 3)
|
||||||
|
errmsg = e_invarg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* sync undo before 'undolevels' changes */
|
/* sync undo before 'undolevels' changes */
|
||||||
else if (pp == &p_ul)
|
else if (pp == &p_ul)
|
||||||
{
|
{
|
||||||
|
@ -694,6 +694,9 @@ EXTERN char_u *p_py3dll; /* 'pythonthreedll' */
|
|||||||
#if defined(DYNAMIC_PYTHON)
|
#if defined(DYNAMIC_PYTHON)
|
||||||
EXTERN char_u *p_pydll; /* 'pythondll' */
|
EXTERN char_u *p_pydll; /* 'pythondll' */
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
|
||||||
|
EXTERN long p_pyx; /* 'pyxversion' */
|
||||||
|
#endif
|
||||||
#ifdef FEAT_RELTIME
|
#ifdef FEAT_RELTIME
|
||||||
EXTERN long p_rdt; /* 'redrawtime' */
|
EXTERN long p_rdt; /* 'redrawtime' */
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,6 +75,10 @@ int do_in_runtimepath(char_u *name, int flags, void (*callback)(char_u *fname, v
|
|||||||
void ex_packloadall(exarg_T *eap);
|
void ex_packloadall(exarg_T *eap);
|
||||||
void ex_packadd(exarg_T *eap);
|
void ex_packadd(exarg_T *eap);
|
||||||
void ex_options(exarg_T *eap);
|
void ex_options(exarg_T *eap);
|
||||||
|
void init_pyxversion(void);
|
||||||
|
void ex_pyxfile(exarg_T *eap);
|
||||||
|
void ex_pyx(exarg_T *eap);
|
||||||
|
void ex_pyxdo(exarg_T *eap);
|
||||||
void ex_source(exarg_T *eap);
|
void ex_source(exarg_T *eap);
|
||||||
linenr_T *source_breakpoint(void *cookie);
|
linenr_T *source_breakpoint(void *cookie);
|
||||||
int *source_dbg_tick(void *cookie);
|
int *source_dbg_tick(void *cookie);
|
||||||
|
@ -176,6 +176,8 @@ NEW_TESTS = test_arglist.res \
|
|||||||
test_packadd.res \
|
test_packadd.res \
|
||||||
test_perl.res \
|
test_perl.res \
|
||||||
test_profile.res \
|
test_profile.res \
|
||||||
|
test_pyx2.res \
|
||||||
|
test_pyx3.res \
|
||||||
test_quickfix.res \
|
test_quickfix.res \
|
||||||
test_retab.res \
|
test_retab.res \
|
||||||
test_ruby.res \
|
test_ruby.res \
|
||||||
|
4
src/testdir/pyxfile/py2_magic.py
Normal file
4
src/testdir/pyxfile/py2_magic.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# requires python 2.x
|
||||||
|
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
4
src/testdir/pyxfile/py2_shebang.py
Normal file
4
src/testdir/pyxfile/py2_shebang.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/python2
|
||||||
|
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
4
src/testdir/pyxfile/py3_magic.py
Normal file
4
src/testdir/pyxfile/py3_magic.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# requires python 3.x
|
||||||
|
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
4
src/testdir/pyxfile/py3_shebang.py
Normal file
4
src/testdir/pyxfile/py3_shebang.py
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
2
src/testdir/pyxfile/pyx.py
Normal file
2
src/testdir/pyxfile/pyx.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
import sys
|
||||||
|
print(sys.version)
|
74
src/testdir/test_pyx2.vim
Normal file
74
src/testdir/test_pyx2.vim
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
" Test for pyx* commands and functions with Python 2.
|
||||||
|
|
||||||
|
set pyx=2
|
||||||
|
if !has('python')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:py2pattern = '^2\.[0-7]\.\d\+'
|
||||||
|
let s:py3pattern = '^3\.\d\+\.\d\+'
|
||||||
|
|
||||||
|
|
||||||
|
func Test_has_pythonx()
|
||||||
|
call assert_true(has('pythonx'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyx()
|
||||||
|
redir => var
|
||||||
|
pyx << EOF
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
||||||
|
EOF
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxdo()
|
||||||
|
pyx import sys
|
||||||
|
enew
|
||||||
|
pyxdo return sys.version.split("\n")[0]
|
||||||
|
call assert_match(s:py2pattern, split(getline('.'))[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxeval()
|
||||||
|
pyx import sys
|
||||||
|
call assert_match(s:py2pattern, split(pyxeval('sys.version'))[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxfile()
|
||||||
|
" No special comments nor shebangs
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/pyx.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 2 special comment
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py2_magic.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 2 shebang
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py2_shebang.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
|
||||||
|
if has('python3')
|
||||||
|
" Python 3 special comment
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py3_magic.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 3 shebang
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py3_shebang.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
endif
|
||||||
|
endfunc
|
74
src/testdir/test_pyx3.vim
Normal file
74
src/testdir/test_pyx3.vim
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
" Test for pyx* commands and functions with Python 3.
|
||||||
|
|
||||||
|
set pyx=3
|
||||||
|
if !has('python3')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
let s:py2pattern = '^2\.[0-7]\.\d\+'
|
||||||
|
let s:py3pattern = '^3\.\d\+\.\d\+'
|
||||||
|
|
||||||
|
|
||||||
|
func Test_has_pythonx()
|
||||||
|
call assert_true(has('pythonx'))
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyx()
|
||||||
|
redir => var
|
||||||
|
pyx << EOF
|
||||||
|
import sys
|
||||||
|
print(sys.version)
|
||||||
|
EOF
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxdo()
|
||||||
|
pyx import sys
|
||||||
|
enew
|
||||||
|
pyxdo return sys.version.split("\n")[0]
|
||||||
|
call assert_match(s:py3pattern, split(getline('.'))[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxeval()
|
||||||
|
pyx import sys
|
||||||
|
call assert_match(s:py3pattern, split(pyxeval('sys.version'))[0])
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
|
||||||
|
func Test_pyxfile()
|
||||||
|
" No special comments nor shebangs
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/pyx.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 3 special comment
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py3_magic.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 3 shebang
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py3_shebang.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py3pattern, split(var)[0])
|
||||||
|
|
||||||
|
if has('python')
|
||||||
|
" Python 2 special comment
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py2_magic.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
|
||||||
|
" Python 2 shebang
|
||||||
|
redir => var
|
||||||
|
pyxfile pyxfile/py2_shebang.py
|
||||||
|
redir END
|
||||||
|
call assert_match(s:py2pattern, split(var)[0])
|
||||||
|
endif
|
||||||
|
endfunc
|
@ -2102,7 +2102,9 @@ ex_function(exarg_T *eap)
|
|||||||
arg = skipwhite(skiptowhite(p));
|
arg = skipwhite(skiptowhite(p));
|
||||||
if (arg[0] == '<' && arg[1] =='<'
|
if (arg[0] == '<' && arg[1] =='<'
|
||||||
&& ((p[0] == 'p' && p[1] == 'y'
|
&& ((p[0] == 'p' && p[1] == 'y'
|
||||||
&& (!ASCII_ISALPHA(p[2]) || p[2] == 't'))
|
&& (!ASCII_ISALNUM(p[2]) || p[2] == 't'
|
||||||
|
|| ((p[2] == '3' || p[2] == 'x')
|
||||||
|
&& !ASCII_ISALPHA(p[3]))))
|
||||||
|| (p[0] == 'p' && p[1] == 'e'
|
|| (p[0] == 'p' && p[1] == 'e'
|
||||||
&& (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
|
&& (!ASCII_ISALPHA(p[2]) || p[2] == 'r'))
|
||||||
|| (p[0] == 't' && p[1] == 'c'
|
|| (p[0] == 't' && p[1] == 'c'
|
||||||
|
@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
251,
|
||||||
/**/
|
/**/
|
||||||
250,
|
250,
|
||||||
/**/
|
/**/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user