On Wed, May 15, 2013 at 06:58:53PM +0200, Bram Moolenaar wrote:
> [...]
>
> There is a ":py3do" command now, but not a ":pydo" command.
> 
> [...]

Attached patch adds this.

-- 
Best regards,
lilydjwg

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt
index c560367..59eeca7 100644
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -57,6 +57,22 @@ Example: >
 Note: Python is very sensitive to the indenting.  Make sure the "class" line
 and "EOF" do not have any indent.
 
+                                                       *:pydo*
+:[range]pydo {body}    Execute Python function "def _vim_pydo(line, linenr):
+                       {body}" for each line in the [range], with the
+                       function arguments being set to the text of each line
+                       in turn, without a trailing <EOL>, and the current
+                       line number. The function should return a string or
+                       None. If a string is returned, it becomes the text of
+                       the line in the current turn. The default for [range]
+                       is the whole file: "1,$".
+                       {not in Vi}
+
+Examples:
+>
+       :pydo return "%s\t%d" % (line[::-1], len(line))
+       :pydo if line: return "%4d: %s" % (linenr, line)
+<
                                                        *:pyfile* *:pyf*
 :[range]pyf[ile] {file}
                        Execute the Python script in {file}.  The whole
@@ -491,20 +507,7 @@ if the `:py3` command is working: >
 The |:py3file| command works similar to |:pyfile|.
 
                                                        *:py3do*
-:[range]py3do {body}   Execute Python function "def _vim_pydo(line, linenr):
-                       {body}" for each line in the [range], with the
-                       function arguments being set to the text of each line
-                       in turn, without a trailing <EOL>, and the current
-                       line number. The function should return a string or
-                       None. If a string is returned, it becomes the text of
-                       the line in the current turn. The default for [range]
-                       is the whole file: "1,$".
-                       {not in Vi}
-
-Examples:
->
-       :py3do return "%s\t%d" % (line[::-1], len(line))
-       :py3do if line: return "%4d: %s" % (linenr, line)
+The |:py3do| command works similar to |:pydo|.
 
 Vim can be built in four ways (:version output):
 1. No Python support       (-python, -python3)
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index b9ad364..75e1724 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -739,6 +739,8 @@ EX(CMD_pwd,         "pwd",          ex_pwd,
                        TRLBAR|CMDWIN),
 EX(CMD_python,         "python",       ex_python,
                        RANGE|EXTRA|NEEDARG|CMDWIN),
+EX(CMD_pydo,           "pydo",         ex_pydo,
+                       RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
 EX(CMD_pyfile,         "pyfile",       ex_pyfile,
                        RANGE|FILE1|NEEDARG|CMDWIN),
 EX(CMD_py3,            "py3",          ex_py3,
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 5ce0b5d..056339e 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -268,6 +268,7 @@ static void ex_popup __ARGS((exarg_T *eap));
 #endif
 #ifndef FEAT_PYTHON
 # define ex_python             ex_script_ni
+# define ex_pydo               ex_ni
 # define ex_pyfile             ex_ni
 #endif
 #ifndef FEAT_PYTHON3
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 4bd5bae..f4077b0 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -22,6 +22,7 @@ typedef int Py_ssize_t;  /* Python 2.4 and earlier don't have 
this type. */
 #else
 # define ENC_OPT "latin1"
 #endif
+#define DOPY_FUNC "_vim_pydo"
 
 #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
 
diff --git a/src/if_python.c b/src/if_python.c
index 134e7f9..2c92b5c 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},
@@ -1000,6 +1009,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().
  */
diff --git a/src/if_python3.c b/src/if_python3.c
index 18987b7..9b8912b 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -76,7 +76,6 @@ static void init_structs(void);
 #else
 # define CODEC_ERROR_HANDLER NULL
 #endif
-#define DOPY_FUNC "_vim_pydo"
 
 /* Python 3 does not support CObjects, always use Capsules */
 #define PY_USE_CAPSULE
diff --git a/src/proto/if_python.pro b/src/proto/if_python.pro
index 4ba977c..8aa7674 100644
--- a/src/proto/if_python.pro
+++ b/src/proto/if_python.pro
@@ -3,6 +3,7 @@ int python_enabled __ARGS((int verbose));
 void python_end __ARGS((void));
 int python_loaded __ARGS((void));
 void ex_python __ARGS((exarg_T *eap));
+void ex_pydo __ARGS((exarg_T *eap));
 void ex_pyfile __ARGS((exarg_T *eap));
 void python_buffer_free __ARGS((buf_T *buf));
 void python_window_free __ARGS((win_T *win));

Raspunde prin e-mail lui