Karsten Hopp 45b9fa
To: vim_dev@googlegroups.com
Karsten Hopp 45b9fa
Subject: Patch 7.3.957
Karsten Hopp 45b9fa
Fcc: outbox
Karsten Hopp 45b9fa
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 45b9fa
Mime-Version: 1.0
Karsten Hopp 45b9fa
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 45b9fa
Content-Transfer-Encoding: 8bit
Karsten Hopp 45b9fa
------------
Karsten Hopp 45b9fa
Karsten Hopp 45b9fa
Patch 7.3.957
Karsten Hopp 45b9fa
Problem:    Python does not have a "do" command like Perl or Lua.
Karsten Hopp 45b9fa
Solution:   Add the ":py3do" command. (Lilydjwg)
Karsten Hopp 45b9fa
Files:	    runtime/doc/if_pyth.txt, src/ex_cmds.h, src/ex_docmd.c,
Karsten Hopp 45b9fa
	    src/if_python3.c, src/proto/if_python3.pro
Karsten Hopp 45b9fa
Karsten Hopp 45b9fa
Karsten Hopp 45b9fa
*** ../vim-7.3.956/runtime/doc/if_pyth.txt	2013-05-15 15:51:03.000000000 +0200
Karsten Hopp 45b9fa
--- runtime/doc/if_pyth.txt	2013-05-15 18:04:17.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 490,495 ****
Karsten Hopp 45b9fa
--- 490,510 ----
Karsten Hopp 45b9fa
  <							*:py3file*
Karsten Hopp 45b9fa
  The |:py3file| command works similar to |:pyfile|.
Karsten Hopp 45b9fa
  
Karsten Hopp 45b9fa
+ 							*:py3do*
Karsten Hopp 45b9fa
+ :[range]py3do {body}	Execute Python function "def _vim_pydo(line, linenr):
Karsten Hopp 45b9fa
+ 			{body}" for each line in the [range], with the
Karsten Hopp 45b9fa
+ 			function arguments being set to the text of each line
Karsten Hopp 45b9fa
+ 			in turn, without a trailing <EOL>, and the current
Karsten Hopp 45b9fa
+ 			line number. The function should return a string or
Karsten Hopp 45b9fa
+ 			None. If a string is returned, it becomes the text of
Karsten Hopp 45b9fa
+ 			the line in the current turn. The default for [range]
Karsten Hopp 45b9fa
+ 			is the whole file: "1,$".
Karsten Hopp 45b9fa
+ 			{not in Vi}
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+ Examples:
Karsten Hopp 45b9fa
+ >
Karsten Hopp 45b9fa
+ 	:py3do return "%s\t%d" % (line[::-1], len(line))
Karsten Hopp 45b9fa
+ 	:py3do if line: return "%4d: %s" % (linenr, line)
Karsten Hopp 45b9fa
  
Karsten Hopp 45b9fa
  Vim can be built in four ways (:version output):
Karsten Hopp 45b9fa
  1. No Python support	    (-python, -python3)
Karsten Hopp 45b9fa
*** ../vim-7.3.956/src/ex_cmds.h	2012-11-14 20:52:22.000000000 +0100
Karsten Hopp 45b9fa
--- src/ex_cmds.h	2013-05-15 18:01:55.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 743,748 ****
Karsten Hopp 45b9fa
--- 743,750 ----
Karsten Hopp 45b9fa
  			RANGE|FILE1|NEEDARG|CMDWIN),
Karsten Hopp 45b9fa
  EX(CMD_py3,		"py3",		ex_py3,
Karsten Hopp 45b9fa
  			RANGE|EXTRA|NEEDARG|CMDWIN),
Karsten Hopp 45b9fa
+ EX(CMD_py3do,		"py3do",	ex_py3do,
Karsten Hopp 45b9fa
+ 			RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
Karsten Hopp 45b9fa
  EX(CMD_python3,		"python3",	ex_py3,
Karsten Hopp 45b9fa
  			RANGE|EXTRA|NEEDARG|CMDWIN),
Karsten Hopp 45b9fa
  EX(CMD_py3file,		"py3file",	ex_py3file,
Karsten Hopp 45b9fa
*** ../vim-7.3.956/src/ex_docmd.c	2013-05-07 05:18:15.000000000 +0200
Karsten Hopp 45b9fa
--- src/ex_docmd.c	2013-05-15 18:01:55.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 272,277 ****
Karsten Hopp 45b9fa
--- 272,278 ----
Karsten Hopp 45b9fa
  #endif
Karsten Hopp 45b9fa
  #ifndef FEAT_PYTHON3
Karsten Hopp 45b9fa
  # define ex_py3			ex_script_ni
Karsten Hopp 45b9fa
+ # define ex_py3do		ex_ni
Karsten Hopp 45b9fa
  # define ex_py3file		ex_ni
Karsten Hopp 45b9fa
  #endif
Karsten Hopp 45b9fa
  #ifndef FEAT_TCL
Karsten Hopp 45b9fa
*** ../vim-7.3.956/src/if_python3.c	2013-05-15 17:49:00.000000000 +0200
Karsten Hopp 45b9fa
--- src/if_python3.c	2013-05-15 18:23:30.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 76,81 ****
Karsten Hopp 45b9fa
--- 76,82 ----
Karsten Hopp 45b9fa
  #else
Karsten Hopp 45b9fa
  # define CODEC_ERROR_HANDLER NULL
Karsten Hopp 45b9fa
  #endif
Karsten Hopp 45b9fa
+ #define DOPY_FUNC "_vim_pydo"
Karsten Hopp 45b9fa
  
Karsten Hopp 45b9fa
  /* Python 3 does not support CObjects, always use Capsules */
Karsten Hopp 45b9fa
  #define PY_USE_CAPSULE
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 126,131 ****
Karsten Hopp 45b9fa
--- 127,133 ----
Karsten Hopp 45b9fa
  # define PyErr_PrintEx py3_PyErr_PrintEx
Karsten Hopp 45b9fa
  # define PyErr_NoMemory py3_PyErr_NoMemory
Karsten Hopp 45b9fa
  # define PyErr_Occurred py3_PyErr_Occurred
Karsten Hopp 45b9fa
+ # define PyErr_PrintEx py3_PyErr_PrintEx
Karsten Hopp 45b9fa
  # define PyErr_SetNone py3_PyErr_SetNone
Karsten Hopp 45b9fa
  # define PyErr_SetString py3_PyErr_SetString
Karsten Hopp 45b9fa
  # define PyErr_SetObject py3_PyErr_SetObject
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 148,154 ****
Karsten Hopp 45b9fa
  # define PyTuple_GetItem py3_PyTuple_GetItem
Karsten Hopp 45b9fa
  # define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
Karsten Hopp 45b9fa
  # define PyImport_ImportModule py3_PyImport_ImportModule
Karsten Hopp 45b9fa
- # define PyImport_AddModule py3_PyImport_AddModule
Karsten Hopp 45b9fa
  # define PyObject_Init py3__PyObject_Init
Karsten Hopp 45b9fa
  # define PyDict_New py3_PyDict_New
Karsten Hopp 45b9fa
  # define PyDict_GetItemString py3_PyDict_GetItemString
Karsten Hopp 45b9fa
--- 150,155 ----
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 163,168 ****
Karsten Hopp 45b9fa
--- 164,174 ----
Karsten Hopp 45b9fa
  # define PyRun_SimpleString py3_PyRun_SimpleString
Karsten Hopp 45b9fa
  #undef PyRun_String
Karsten Hopp 45b9fa
  # define PyRun_String py3_PyRun_String
Karsten Hopp 45b9fa
+ # define PyObject_GetAttrString py3_PyObject_GetAttrString
Karsten Hopp 45b9fa
+ # define PyObject_SetAttrString py3_PyObject_SetAttrString
Karsten Hopp 45b9fa
+ # define PyObject_CallFunctionObjArgs py3_PyObject_CallFunctionObjArgs
Karsten Hopp 45b9fa
+ # define PyEval_GetLocals py3_PyEval_GetLocals
Karsten Hopp 45b9fa
+ # define PyEval_GetGlobals py3_PyEval_GetGlobals
Karsten Hopp 45b9fa
  # define PySys_SetObject py3_PySys_SetObject
Karsten Hopp 45b9fa
  # define PySys_SetArgv py3_PySys_SetArgv
Karsten Hopp 45b9fa
  # define PyType_Ready py3_PyType_Ready
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 178,183 ****
Karsten Hopp 45b9fa
--- 184,190 ----
Karsten Hopp 45b9fa
  # define _PyObject_NextNotImplemented (*py3__PyObject_NextNotImplemented)
Karsten Hopp 45b9fa
  # define PyModule_AddObject py3_PyModule_AddObject
Karsten Hopp 45b9fa
  # define PyImport_AppendInittab py3_PyImport_AppendInittab
Karsten Hopp 45b9fa
+ # define PyImport_AddModule py3_PyImport_AddModule
Karsten Hopp 45b9fa
  # if PY_VERSION_HEX >= 0x030300f0
Karsten Hopp 45b9fa
  #  undef _PyUnicode_AsString
Karsten Hopp 45b9fa
  #  define _PyUnicode_AsString py3_PyUnicode_AsUTF8
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 254,259 ****
Karsten Hopp 45b9fa
--- 261,271 ----
Karsten Hopp 45b9fa
  static void (*py3_PyErr_SetObject)(PyObject *, PyObject *);
Karsten Hopp 45b9fa
  static int (*py3_PyRun_SimpleString)(char *);
Karsten Hopp 45b9fa
  static PyObject* (*py3_PyRun_String)(char *, int, PyObject *, PyObject *);
Karsten Hopp 45b9fa
+ static PyObject* (*py3_PyObject_GetAttrString)(PyObject *, const char *);
Karsten Hopp 45b9fa
+ static PyObject* (*py3_PyObject_SetAttrString)(PyObject *, const char *, PyObject *);
Karsten Hopp 45b9fa
+ static PyObject* (*py3_PyObject_CallFunctionObjArgs)(PyObject *, ...);
Karsten Hopp 45b9fa
+ static PyObject* (*py3_PyEval_GetGlobals)();
Karsten Hopp 45b9fa
+ static PyObject* (*py3_PyEval_GetLocals)();
Karsten Hopp 45b9fa
  static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
Karsten Hopp 45b9fa
  static PyObject* (*py3_PyImport_ImportModule)(const char *);
Karsten Hopp 45b9fa
  static PyObject* (*py3_PyImport_AddModule)(const char *);
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 386,391 ****
Karsten Hopp 45b9fa
--- 398,408 ----
Karsten Hopp 45b9fa
      {"PyErr_SetObject", (PYTHON_PROC*)&py3_PyErr_SetObject},
Karsten Hopp 45b9fa
      {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
Karsten Hopp 45b9fa
      {"PyRun_String", (PYTHON_PROC*)&py3_PyRun_String},
Karsten Hopp 45b9fa
+     {"PyObject_GetAttrString", (PYTHON_PROC*)&py3_PyObject_GetAttrString},
Karsten Hopp 45b9fa
+     {"PyObject_SetAttrString", (PYTHON_PROC*)&py3_PyObject_SetAttrString},
Karsten Hopp 45b9fa
+     {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&py3_PyObject_CallFunctionObjArgs},
Karsten Hopp 45b9fa
+     {"PyEval_GetGlobals", (PYTHON_PROC*)&py3_PyEval_GetGlobals},
Karsten Hopp 45b9fa
+     {"PyEval_GetLocals", (PYTHON_PROC*)&py3_PyEval_GetLocals},
Karsten Hopp 45b9fa
      {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
Karsten Hopp 45b9fa
      {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
Karsten Hopp 45b9fa
      {"PyImport_AddModule", (PYTHON_PROC*)&py3_PyImport_AddModule},
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 990,995 ****
Karsten Hopp 45b9fa
--- 1007,1106 ----
Karsten Hopp 45b9fa
      DoPy3Command(eap, buffer, NULL);
Karsten Hopp 45b9fa
  }
Karsten Hopp 45b9fa
  
Karsten Hopp 45b9fa
+ void ex_py3do(exarg_T *eap)
Karsten Hopp 45b9fa
+ {
Karsten Hopp 45b9fa
+     linenr_T		i;
Karsten Hopp 45b9fa
+     const char		*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
Karsten Hopp 45b9fa
+     const char		*s = (const char *) eap->arg;
Karsten Hopp 45b9fa
+     size_t		len;
Karsten Hopp 45b9fa
+     char		*code;
Karsten Hopp 45b9fa
+     int			status;
Karsten Hopp 45b9fa
+     PyObject		*pyfunc, *pymain;
Karsten Hopp 45b9fa
+     PyGILState_STATE	pygilstate;
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+     if (Python3_Init())
Karsten Hopp 45b9fa
+ 	goto theend;
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+     if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
Karsten Hopp 45b9fa
+     {
Karsten Hopp 45b9fa
+ 	EMSG(_("cannot save undo information"));
Karsten Hopp 45b9fa
+ 	return;
Karsten Hopp 45b9fa
+     }
Karsten Hopp 45b9fa
+     len = strlen(code_hdr) + strlen(s);
Karsten Hopp 45b9fa
+     code = malloc(len + 1);
Karsten Hopp 45b9fa
+     STRCPY(code, code_hdr);
Karsten Hopp 45b9fa
+     STRNCAT(code, s, len + 1);
Karsten Hopp 45b9fa
+     pygilstate = PyGILState_Ensure();
Karsten Hopp 45b9fa
+     status = PyRun_SimpleString(code);
Karsten Hopp 45b9fa
+     vim_free(code);
Karsten Hopp 45b9fa
+     if (status)
Karsten Hopp 45b9fa
+     {
Karsten Hopp 45b9fa
+ 	EMSG(_("failed to run the code"));
Karsten Hopp 45b9fa
+ 	return;
Karsten Hopp 45b9fa
+     }
Karsten Hopp 45b9fa
+     status = 0; /* good */
Karsten Hopp 45b9fa
+     pymain = PyImport_AddModule("__main__");
Karsten Hopp 45b9fa
+     pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Karsten Hopp 45b9fa
+     PyGILState_Release(pygilstate);
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+     for (i = eap->line1; i <= eap->line2; i++)
Karsten Hopp 45b9fa
+     {
Karsten Hopp 45b9fa
+ 	const char *line;
Karsten Hopp 45b9fa
+ 	PyObject *pyline, *pylinenr, *pyret, *pybytes;
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+ 	line = (char *)ml_get(i);
Karsten Hopp 45b9fa
+ 	pygilstate = PyGILState_Ensure();
Karsten Hopp 45b9fa
+ 	pyline = PyUnicode_Decode(line, strlen(line),
Karsten Hopp 45b9fa
+ 		(char *)ENC_OPT, CODEC_ERROR_HANDLER);
Karsten Hopp 45b9fa
+ 	pylinenr = PyLong_FromLong(i);
Karsten Hopp 45b9fa
+ 	pyret = PyObject_CallFunctionObjArgs(pyfunc, pyline, pylinenr, NULL);
Karsten Hopp 45b9fa
+ 	Py_DECREF(pyline);
Karsten Hopp 45b9fa
+ 	Py_DECREF(pylinenr);
Karsten Hopp 45b9fa
+ 	if (!pyret)
Karsten Hopp 45b9fa
+ 	{
Karsten Hopp 45b9fa
+ 	    PyErr_PrintEx(0);
Karsten Hopp 45b9fa
+ 	    PythonIO_Flush();
Karsten Hopp 45b9fa
+ 	    status = 1;
Karsten Hopp 45b9fa
+ 	    goto out;
Karsten Hopp 45b9fa
+ 	}
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+ 	if (pyret && pyret != Py_None)
Karsten Hopp 45b9fa
+ 	{
Karsten Hopp 45b9fa
+ 	    if (!PyUnicode_Check(pyret))
Karsten Hopp 45b9fa
+ 	    {
Karsten Hopp 45b9fa
+ 		/* TODO: a proper error number */
Karsten Hopp 45b9fa
+ 		EMSG(_("E000: return value must be an instance of str"));
Karsten Hopp 45b9fa
+ 		Py_XDECREF(pyret);
Karsten Hopp 45b9fa
+ 		status = 1;
Karsten Hopp 45b9fa
+ 		goto out;
Karsten Hopp 45b9fa
+ 	    }
Karsten Hopp 45b9fa
+ 	    pybytes = PyUnicode_AsEncodedString(pyret,
Karsten Hopp 45b9fa
+ 		    (char *)ENC_OPT, CODEC_ERROR_HANDLER);
Karsten Hopp 45b9fa
+ 	    ml_replace(i, (char_u *) PyBytes_AsString(pybytes), 1);
Karsten Hopp 45b9fa
+ 	    Py_DECREF(pybytes);
Karsten Hopp 45b9fa
+ 	    changed();
Karsten Hopp 45b9fa
+ #ifdef SYNTAX_HL
Karsten Hopp 45b9fa
+ 	    syn_changed(i); /* recompute syntax hl. for this line */
Karsten Hopp 45b9fa
+ #endif
Karsten Hopp 45b9fa
+ 	}
Karsten Hopp 45b9fa
+ 	Py_XDECREF(pyret);
Karsten Hopp 45b9fa
+ 	PythonIO_Flush();
Karsten Hopp 45b9fa
+ 	PyGILState_Release(pygilstate);
Karsten Hopp 45b9fa
+     }
Karsten Hopp 45b9fa
+     pygilstate = PyGILState_Ensure();
Karsten Hopp 45b9fa
+ out:
Karsten Hopp 45b9fa
+     Py_DECREF(pyfunc);
Karsten Hopp 45b9fa
+     PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
Karsten Hopp 45b9fa
+     PyGILState_Release(pygilstate);
Karsten Hopp 45b9fa
+     if (status)
Karsten Hopp 45b9fa
+ 	return;
Karsten Hopp 45b9fa
+     check_cursor();
Karsten Hopp 45b9fa
+     update_curbuf(NOT_VALID);
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
+ theend:
Karsten Hopp 45b9fa
+     return;
Karsten Hopp 45b9fa
+ }
Karsten Hopp 45b9fa
+ 
Karsten Hopp 45b9fa
  /******************************************************
Karsten Hopp 45b9fa
   * 2. Python output stream: writes output via [e]msg().
Karsten Hopp 45b9fa
   */
Karsten Hopp 45b9fa
*** ../vim-7.3.956/src/proto/if_python3.pro	2013-05-15 15:12:25.000000000 +0200
Karsten Hopp 45b9fa
--- src/proto/if_python3.pro	2013-05-15 18:01:55.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 3,8 ****
Karsten Hopp 45b9fa
--- 3,9 ----
Karsten Hopp 45b9fa
  void python3_end __ARGS((void));
Karsten Hopp 45b9fa
  int python3_loaded __ARGS((void));
Karsten Hopp 45b9fa
  void ex_py3 __ARGS((exarg_T *eap));
Karsten Hopp 45b9fa
+ void ex_py3do __ARGS((exarg_T *eap));
Karsten Hopp 45b9fa
  void ex_py3file __ARGS((exarg_T *eap));
Karsten Hopp 45b9fa
  void python3_buffer_free __ARGS((buf_T *buf));
Karsten Hopp 45b9fa
  void python3_window_free __ARGS((win_T *win));
Karsten Hopp 45b9fa
*** ../vim-7.3.956/src/version.c	2013-05-15 17:49:00.000000000 +0200
Karsten Hopp 45b9fa
--- src/version.c	2013-05-15 18:16:28.000000000 +0200
Karsten Hopp 45b9fa
***************
Karsten Hopp 45b9fa
*** 730,731 ****
Karsten Hopp 45b9fa
--- 730,733 ----
Karsten Hopp 45b9fa
  {   /* Add new patch number below this line */
Karsten Hopp 45b9fa
+ /**/
Karsten Hopp 45b9fa
+     957,
Karsten Hopp 45b9fa
  /**/
Karsten Hopp 45b9fa
Karsten Hopp 45b9fa
-- 
Karsten Hopp 45b9fa
FATHER: We are here today to witness the union of two young people in the
Karsten Hopp 45b9fa
        joyful bond of the holy wedlock.  Unfortunately, one of them, my son
Karsten Hopp 45b9fa
        Herbert, has just fallen to his death.
Karsten Hopp 45b9fa
   [Murmurs from CROWD;  the BRIDE smiles with relief, coughs.]
Karsten Hopp 45b9fa
                 "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD
Karsten Hopp 45b9fa
Karsten Hopp 45b9fa
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 45b9fa
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 45b9fa
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 45b9fa
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///