aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds2.c
diff options
context:
space:
mode:
authorDavid Jimenez <dvejmz@users.noreply.github.com>2019-01-02 13:51:03 +0000
committerJustin M. Keyes <justinkz@gmail.com>2019-01-02 14:51:03 +0100
commit8f288698e4730f6cc91240fe899e93921aff9d71 (patch)
tree638a46ca5a47d9613ad9957ae5498605817e2404 /src/nvim/ex_cmds2.c
parent5a11e553588f90f3c945222d89ee3ff80cfc3fc7 (diff)
downloadrneovim-8f288698e4730f6cc91240fe899e93921aff9d71.tar.gz
rneovim-8f288698e4730f6cc91240fe899e93921aff9d71.tar.bz2
rneovim-8f288698e4730f6cc91240fe899e93921aff9d71.zip
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) https://github.com/vim/vim/commit/f42dd3c3901ea0ba38e67a616aea9953cae81b8d
Diffstat (limited to 'src/nvim/ex_cmds2.c')
-rw-r--r--src/nvim/ex_cmds2.c120
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)
{