vim-patch:8.0.0251: not easy to select Python 2 or 3 (#9173)

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)

f42dd3c390
This commit is contained in:
David Jimenez
2019-01-02 13:51:03 +00:00
committed by Justin M. Keyes
parent 5a11e55358
commit 8f288698e4
21 changed files with 447 additions and 2 deletions

View File

@@ -2809,6 +2809,126 @@ void ex_options(exarg_T *eap)
cmd_source((char_u *)SYS_OPTWIN_FILE, NULL);
}
// Detect Python 3 or 2, and initialize 'pyxversion'.
void init_pyxversion(void)
{
if (p_pyx == 0) {
if (!eval_has_provider("python3")) {
p_pyx = 3;
} else if (!eval_has_provider("python")) {
p_pyx = 2;
}
}
}
// 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;
long int v = requires_py_version(fname);
init_pyxversion();
if (v == 0) {
// user didn't choose a preference, 'pyx' is used
v = p_pyx;
}
// now source, if required python version is not supported show
// unobtrusive message.
if (eap == NULL) {
memset(&ex, 0, sizeof(ex));
} else {
ex = *eap;
}
ex.arg = fname;
ex.cmd = (char_u *)(v == 2 ? "pyfile" : "pyfile3");
if (v == 2) {
ex_pyfile(&ex);
} else {
ex_py3file(&ex);
}
}
// ":pyxfile {fname}"
void ex_pyxfile(exarg_T *eap)
{
source_pyx_file(eap, eap->arg);
}
// ":pyx"
void ex_pyx(exarg_T *eap)
{
init_pyxversion();
if (p_pyx == 2) {
ex_python(eap);
} else {
ex_python3(eap);
}
}
// ":pyxdo"
void ex_pyxdo(exarg_T *eap)
{
init_pyxversion();
if (p_pyx == 2) {
ex_pydo(eap);
} else {
ex_pydo3(eap);
}
}
/// ":source {fname}"
void ex_source(exarg_T *eap)
{