diff options
Diffstat (limited to 'src/nvim/ex_cmds2.c')
-rw-r--r-- | src/nvim/ex_cmds2.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 1ffcf67ef7..51d20c746a 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -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) { |