diff options
author | Bram Moolenaar <Bram@vim.org> | 2013-05-17 16:40:06 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2013-05-17 16:40:06 +0200 |
commit | d620aa9be4d574627c020dedd39313f8482ab216 (patch) | |
tree | 624b63e85141e01e5ac4c3b200a842f4719e6d6e /src/if_python.c | |
parent | cfef5ff23ea09b17203d9f466f6f3526c76a8b99 (diff) | |
download | vim-git-d620aa9be4d574627c020dedd39313f8482ab216.tar.gz |
updated for version 7.3.966v7.3.966
Problem: There is ":py3do" but no ":pydo".
Solution: Add the ":pydo" command. (Lilydjwg)
Diffstat (limited to 'src/if_python.c')
-rw-r--r-- | src/if_python.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/if_python.c b/src/if_python.c index baa8cab87..5874103f0 100644 --- a/src/if_python.c +++ b/src/if_python.c @@ -198,6 +198,9 @@ struct PyMethodDef { Py_ssize_t a; }; # define PyModule_GetDict dll_PyModule_GetDict # define PyRun_SimpleString dll_PyRun_SimpleString # define PyRun_String dll_PyRun_String +# define PyObject_GetAttrString dll_PyObject_GetAttrString +# define PyObject_SetAttrString dll_PyObject_SetAttrString +# define PyObject_CallFunctionObjArgs dll_PyObject_CallFunctionObjArgs # define PyString_AsString dll_PyString_AsString # define PyString_AsStringAndSize dll_PyString_AsStringAndSize # define PyString_FromString dll_PyString_FromString @@ -303,6 +306,9 @@ static PyObject* (*dll_PyIter_Next)(PyObject *); static PyObject*(*dll_PyModule_GetDict)(PyObject *); static int(*dll_PyRun_SimpleString)(char *); static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *); +static PyObject* (*dll_PyObject_GetAttrString)(PyObject *, const char *); +static PyObject* (*dll_PyObject_SetAttrString)(PyObject *, const char *, PyObject *); +static PyObject* (*dll_PyObject_CallFunctionObjArgs)(PyObject *, ...); static char*(*dll_PyString_AsString)(PyObject *); static int(*dll_PyString_AsStringAndSize)(PyObject *, char **, int *); static PyObject*(*dll_PyString_FromString)(const char *); @@ -440,6 +446,9 @@ static struct {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict}, {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString}, {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String}, + {"PyObject_GetAttrString", (PYTHON_PROC*)&dll_PyObject_GetAttrString}, + {"PyObject_SetAttrString", (PYTHON_PROC*)&dll_PyObject_SetAttrString}, + {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&dll_PyObject_CallFunctionObjArgs}, {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString}, {"PyString_AsStringAndSize", (PYTHON_PROC*)&dll_PyString_AsStringAndSize}, {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString}, @@ -995,6 +1004,93 @@ ex_pyfile(exarg_T *eap) DoPythonCommand(eap, buffer, NULL); } + void +ex_pydo(exarg_T *eap) +{ + linenr_T i; + const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n "; + const char *s = (const char *) eap->arg; + size_t len; + char *code; + int status; + PyObject *pyfunc, *pymain; + PyGILState_STATE pygilstate; + + if (Python_Init()) + return; + + if (u_save(eap->line1 - 1, eap->line2 + 1) != OK) + { + EMSG(_("cannot save undo information")); + return; + } + len = strlen(code_hdr) + strlen(s); + code = malloc(len + 1); + STRCPY(code, code_hdr); + STRNCAT(code, s, len + 1); + pygilstate = PyGILState_Ensure(); + status = PyRun_SimpleString(code); + vim_free(code); + if (status) + { + EMSG(_("failed to run the code")); + return; + } + status = 0; /* good */ + pymain = PyImport_AddModule("__main__"); + pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC); + PyGILState_Release(pygilstate); + + for (i = eap->line1; i <= eap->line2; i++) + { + const char *line; + PyObject *pyline, *pylinenr, *pyret; + + line = (char *)ml_get(i); + pygilstate = PyGILState_Ensure(); + pyline = PyString_FromStringAndSize(line, strlen(line)); + pylinenr = PyLong_FromLong(i); + pyret = PyObject_CallFunctionObjArgs(pyfunc, pyline, pylinenr, NULL); + Py_DECREF(pyline); + Py_DECREF(pylinenr); + if (!pyret) + { + PyErr_PrintEx(0); + PythonIO_Flush(); + status = 1; + goto out; + } + + if (pyret && pyret != Py_None) + { + if (!PyString_Check(pyret)) + { + EMSG(_("E863: return value must be an instance of str")); + Py_XDECREF(pyret); + status = 1; + goto out; + } + ml_replace(i, (char_u *) PyString_AsString(pyret), 1); + changed(); +#ifdef SYNTAX_HL + syn_changed(i); /* recompute syntax hl. for this line */ +#endif + } + Py_XDECREF(pyret); + PythonIO_Flush(); + PyGILState_Release(pygilstate); + } + pygilstate = PyGILState_Ensure(); +out: + Py_DECREF(pyfunc); + PyObject_SetAttrString(pymain, DOPY_FUNC, NULL); + PyGILState_Release(pygilstate); + if (status) + return; + check_cursor(); + update_curbuf(NOT_VALID); +} + /****************************************************** * 2. Python output stream: writes output via [e]msg(). */ |