Karsten Hopp 193f84
To: vim_dev@googlegroups.com
Karsten Hopp 193f84
Subject: Patch 7.3.966
Karsten Hopp 193f84
Fcc: outbox
Karsten Hopp 193f84
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 193f84
Mime-Version: 1.0
Karsten Hopp 193f84
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 193f84
Content-Transfer-Encoding: 8bit
Karsten Hopp 193f84
------------
Karsten Hopp 193f84
Karsten Hopp 193f84
Patch 7.3.966
Karsten Hopp 193f84
Problem:    There is ":py3do" but no ":pydo".
Karsten Hopp 193f84
Solution:   Add the ":pydo" command. (Lilydjwg)
Karsten Hopp 193f84
Files:	    runtime/doc/if_pyth.txt, src/ex_cmds.h, src/ex_docmd.c,
Karsten Hopp 193f84
	    src/if_py_both.h, src/if_python.c, src/if_python3.c,
Karsten Hopp 193f84
	    src/proto/if_python.pro
Karsten Hopp 193f84
Karsten Hopp 193f84
Karsten Hopp 193f84
*** ../vim-7.3.965/runtime/doc/if_pyth.txt	2013-05-17 16:18:27.000000000 +0200
Karsten Hopp 193f84
--- runtime/doc/if_pyth.txt	2013-05-17 16:34:28.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 57,62 ****
Karsten Hopp 193f84
--- 57,78 ----
Karsten Hopp 193f84
  Note: Python is very sensitive to the indenting.  Make sure the "class" line
Karsten Hopp 193f84
  and "EOF" do not have any indent.
Karsten Hopp 193f84
  
Karsten Hopp 193f84
+ 							*:pydo*
Karsten Hopp 193f84
+ :[range]pydo {body}	Execute Python function "def _vim_pydo(line, linenr):
Karsten Hopp 193f84
+ 			{body}" for each line in the [range], with the
Karsten Hopp 193f84
+ 			function arguments being set to the text of each line
Karsten Hopp 193f84
+ 			in turn, without a trailing <EOL>, and the current
Karsten Hopp 193f84
+ 			line number. The function should return a string or
Karsten Hopp 193f84
+ 			None. If a string is returned, it becomes the text of
Karsten Hopp 193f84
+ 			the line in the current turn. The default for [range]
Karsten Hopp 193f84
+ 			is the whole file: "1,$".
Karsten Hopp 193f84
+ 			{not in Vi}
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+ Examples:
Karsten Hopp 193f84
+ >
Karsten Hopp 193f84
+ 	:pydo return "%s\t%d" % (line[::-1], len(line))
Karsten Hopp 193f84
+ 	:pydo if line: return "%4d: %s" % (linenr, line)
Karsten Hopp 193f84
+ <
Karsten Hopp 193f84
  							*:pyfile* *:pyf*
Karsten Hopp 193f84
  :[range]pyf[ile] {file}
Karsten Hopp 193f84
  			Execute the Python script in {file}.  The whole
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 485,511 ****
Karsten Hopp 193f84
  8. Python 3						*python3*
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  							*:py3* *:python3*
Karsten Hopp 193f84
! The |:py3| and |:python3| commands work similar to |:python|.  A simple check
Karsten Hopp 193f84
  if the `:py3` command is working: >
Karsten Hopp 193f84
  	:py3 print("Hello")
Karsten Hopp 193f84
  <							*:py3file*
Karsten Hopp 193f84
! The |:py3file| command works similar to |:pyfile|.
Karsten Hopp 193f84
! 
Karsten Hopp 193f84
  							*:py3do* *E863*
Karsten Hopp 193f84
! :[range]py3do {body}	Execute Python function "def _vim_pydo(line, linenr):
Karsten Hopp 193f84
! 			{body}" for each line in the [range], with the
Karsten Hopp 193f84
! 			function arguments being set to the text of each line
Karsten Hopp 193f84
! 			in turn, without a trailing <EOL>, and the current
Karsten Hopp 193f84
! 			line number. The function should return a string or
Karsten Hopp 193f84
! 			None. If a string is returned, it becomes the text of
Karsten Hopp 193f84
! 			the line in the current turn. The default for [range]
Karsten Hopp 193f84
! 			is the whole file: "1,$".
Karsten Hopp 193f84
! 			{not in Vi}
Karsten Hopp 193f84
  
Karsten Hopp 193f84
- Examples:
Karsten Hopp 193f84
- >
Karsten Hopp 193f84
- 	:py3do return "%s\t%d" % (line[::-1], len(line))
Karsten Hopp 193f84
- 	:py3do if line: return "%4d: %s" % (linenr, line)
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  Vim can be built in four ways (:version output):
Karsten Hopp 193f84
  1. No Python support	    (-python, -python3)
Karsten Hopp 193f84
--- 501,514 ----
Karsten Hopp 193f84
  8. Python 3						*python3*
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  							*:py3* *:python3*
Karsten Hopp 193f84
! The `:py3` and `:python3` commands work similar to `:python`.  A simple check
Karsten Hopp 193f84
  if the `:py3` command is working: >
Karsten Hopp 193f84
  	:py3 print("Hello")
Karsten Hopp 193f84
  <							*:py3file*
Karsten Hopp 193f84
! The `:py3file` command works similar to `:pyfile`.
Karsten Hopp 193f84
  							*:py3do* *E863*
Karsten Hopp 193f84
! The `:py3do` command works similar to `:pydo`.
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  Vim can be built in four ways (:version output):
Karsten Hopp 193f84
  1. No Python support	    (-python, -python3)
Karsten Hopp 193f84
*** ../vim-7.3.965/src/ex_cmds.h	2013-05-15 18:28:08.000000000 +0200
Karsten Hopp 193f84
--- src/ex_cmds.h	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 739,744 ****
Karsten Hopp 193f84
--- 739,746 ----
Karsten Hopp 193f84
  			TRLBAR|CMDWIN),
Karsten Hopp 193f84
  EX(CMD_python,		"python",	ex_python,
Karsten Hopp 193f84
  			RANGE|EXTRA|NEEDARG|CMDWIN),
Karsten Hopp 193f84
+ EX(CMD_pydo,		"pydo",		ex_pydo,
Karsten Hopp 193f84
+ 			RANGE|DFLALL|EXTRA|NEEDARG|CMDWIN),
Karsten Hopp 193f84
  EX(CMD_pyfile,		"pyfile",	ex_pyfile,
Karsten Hopp 193f84
  			RANGE|FILE1|NEEDARG|CMDWIN),
Karsten Hopp 193f84
  EX(CMD_py3,		"py3",		ex_py3,
Karsten Hopp 193f84
*** ../vim-7.3.965/src/ex_docmd.c	2013-05-15 18:28:08.000000000 +0200
Karsten Hopp 193f84
--- src/ex_docmd.c	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 268,273 ****
Karsten Hopp 193f84
--- 268,274 ----
Karsten Hopp 193f84
  #endif
Karsten Hopp 193f84
  #ifndef FEAT_PYTHON
Karsten Hopp 193f84
  # define ex_python		ex_script_ni
Karsten Hopp 193f84
+ # define ex_pydo		ex_ni
Karsten Hopp 193f84
  # define ex_pyfile		ex_ni
Karsten Hopp 193f84
  #endif
Karsten Hopp 193f84
  #ifndef FEAT_PYTHON3
Karsten Hopp 193f84
*** ../vim-7.3.965/src/if_py_both.h	2013-05-17 16:24:27.000000000 +0200
Karsten Hopp 193f84
--- src/if_py_both.h	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 22,27 ****
Karsten Hopp 193f84
--- 22,28 ----
Karsten Hopp 193f84
  #else
Karsten Hopp 193f84
  # define ENC_OPT "latin1"
Karsten Hopp 193f84
  #endif
Karsten Hopp 193f84
+ #define DOPY_FUNC "_vim_pydo"
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  #define PyErr_SetVim(str) PyErr_SetString(VimError, str)
Karsten Hopp 193f84
  
Karsten Hopp 193f84
*** ../vim-7.3.965/src/if_python.c	2013-05-17 16:18:27.000000000 +0200
Karsten Hopp 193f84
--- src/if_python.c	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 198,203 ****
Karsten Hopp 193f84
--- 198,206 ----
Karsten Hopp 193f84
  # define PyModule_GetDict dll_PyModule_GetDict
Karsten Hopp 193f84
  # define PyRun_SimpleString dll_PyRun_SimpleString
Karsten Hopp 193f84
  # define PyRun_String dll_PyRun_String
Karsten Hopp 193f84
+ # define PyObject_GetAttrString dll_PyObject_GetAttrString
Karsten Hopp 193f84
+ # define PyObject_SetAttrString dll_PyObject_SetAttrString
Karsten Hopp 193f84
+ # define PyObject_CallFunctionObjArgs dll_PyObject_CallFunctionObjArgs
Karsten Hopp 193f84
  # define PyString_AsString dll_PyString_AsString
Karsten Hopp 193f84
  # define PyString_AsStringAndSize dll_PyString_AsStringAndSize
Karsten Hopp 193f84
  # define PyString_FromString dll_PyString_FromString
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 303,308 ****
Karsten Hopp 193f84
--- 306,314 ----
Karsten Hopp 193f84
  static PyObject*(*dll_PyModule_GetDict)(PyObject *);
Karsten Hopp 193f84
  static int(*dll_PyRun_SimpleString)(char *);
Karsten Hopp 193f84
  static PyObject *(*dll_PyRun_String)(char *, int, PyObject *, PyObject *);
Karsten Hopp 193f84
+ static PyObject* (*dll_PyObject_GetAttrString)(PyObject *, const char *);
Karsten Hopp 193f84
+ static PyObject* (*dll_PyObject_SetAttrString)(PyObject *, const char *, PyObject *);
Karsten Hopp 193f84
+ static PyObject* (*dll_PyObject_CallFunctionObjArgs)(PyObject *, ...);
Karsten Hopp 193f84
  static char*(*dll_PyString_AsString)(PyObject *);
Karsten Hopp 193f84
  static int(*dll_PyString_AsStringAndSize)(PyObject *, char **, int *);
Karsten Hopp 193f84
  static PyObject*(*dll_PyString_FromString)(const char *);
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 440,445 ****
Karsten Hopp 193f84
--- 446,454 ----
Karsten Hopp 193f84
      {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
Karsten Hopp 193f84
      {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
Karsten Hopp 193f84
      {"PyRun_String", (PYTHON_PROC*)&dll_PyRun_String},
Karsten Hopp 193f84
+     {"PyObject_GetAttrString", (PYTHON_PROC*)&dll_PyObject_GetAttrString},
Karsten Hopp 193f84
+     {"PyObject_SetAttrString", (PYTHON_PROC*)&dll_PyObject_SetAttrString},
Karsten Hopp 193f84
+     {"PyObject_CallFunctionObjArgs", (PYTHON_PROC*)&dll_PyObject_CallFunctionObjArgs},
Karsten Hopp 193f84
      {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
Karsten Hopp 193f84
      {"PyString_AsStringAndSize", (PYTHON_PROC*)&dll_PyString_AsStringAndSize},
Karsten Hopp 193f84
      {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 995,1000 ****
Karsten Hopp 193f84
--- 1004,1096 ----
Karsten Hopp 193f84
      DoPythonCommand(eap, buffer, NULL);
Karsten Hopp 193f84
  }
Karsten Hopp 193f84
  
Karsten Hopp 193f84
+     void
Karsten Hopp 193f84
+ ex_pydo(exarg_T *eap)
Karsten Hopp 193f84
+ {
Karsten Hopp 193f84
+     linenr_T		i;
Karsten Hopp 193f84
+     const char		*code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
Karsten Hopp 193f84
+     const char		*s = (const char *) eap->arg;
Karsten Hopp 193f84
+     size_t		len;
Karsten Hopp 193f84
+     char		*code;
Karsten Hopp 193f84
+     int			status;
Karsten Hopp 193f84
+     PyObject		*pyfunc, *pymain;
Karsten Hopp 193f84
+     PyGILState_STATE	pygilstate;
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+     if (Python_Init())
Karsten Hopp 193f84
+         return;
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+     if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
Karsten Hopp 193f84
+     {
Karsten Hopp 193f84
+ 	EMSG(_("cannot save undo information"));
Karsten Hopp 193f84
+ 	return;
Karsten Hopp 193f84
+     }
Karsten Hopp 193f84
+     len = strlen(code_hdr) + strlen(s);
Karsten Hopp 193f84
+     code = malloc(len + 1);
Karsten Hopp 193f84
+     STRCPY(code, code_hdr);
Karsten Hopp 193f84
+     STRNCAT(code, s, len + 1);
Karsten Hopp 193f84
+     pygilstate = PyGILState_Ensure();
Karsten Hopp 193f84
+     status = PyRun_SimpleString(code);
Karsten Hopp 193f84
+     vim_free(code);
Karsten Hopp 193f84
+     if (status)
Karsten Hopp 193f84
+     {
Karsten Hopp 193f84
+ 	EMSG(_("failed to run the code"));
Karsten Hopp 193f84
+ 	return;
Karsten Hopp 193f84
+     }
Karsten Hopp 193f84
+     status = 0; /* good */
Karsten Hopp 193f84
+     pymain = PyImport_AddModule("__main__");
Karsten Hopp 193f84
+     pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Karsten Hopp 193f84
+     PyGILState_Release(pygilstate);
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+     for (i = eap->line1; i <= eap->line2; i++)
Karsten Hopp 193f84
+     {
Karsten Hopp 193f84
+ 	const char *line;
Karsten Hopp 193f84
+ 	PyObject *pyline, *pylinenr, *pyret;
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+ 	line = (char *)ml_get(i);
Karsten Hopp 193f84
+ 	pygilstate = PyGILState_Ensure();
Karsten Hopp 193f84
+ 	pyline = PyString_FromStringAndSize(line, strlen(line));
Karsten Hopp 193f84
+ 	pylinenr = PyLong_FromLong(i);
Karsten Hopp 193f84
+ 	pyret = PyObject_CallFunctionObjArgs(pyfunc, pyline, pylinenr, NULL);
Karsten Hopp 193f84
+ 	Py_DECREF(pyline);
Karsten Hopp 193f84
+ 	Py_DECREF(pylinenr);
Karsten Hopp 193f84
+ 	if (!pyret)
Karsten Hopp 193f84
+ 	{
Karsten Hopp 193f84
+ 	    PyErr_PrintEx(0);
Karsten Hopp 193f84
+ 	    PythonIO_Flush();
Karsten Hopp 193f84
+ 	    status = 1;
Karsten Hopp 193f84
+ 	    goto out;
Karsten Hopp 193f84
+ 	}
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
+ 	if (pyret && pyret != Py_None)
Karsten Hopp 193f84
+ 	{
Karsten Hopp 193f84
+ 	    if (!PyString_Check(pyret))
Karsten Hopp 193f84
+ 	    {
Karsten Hopp 193f84
+ 		EMSG(_("E863: return value must be an instance of str"));
Karsten Hopp 193f84
+ 		Py_XDECREF(pyret);
Karsten Hopp 193f84
+ 		status = 1;
Karsten Hopp 193f84
+ 		goto out;
Karsten Hopp 193f84
+ 	    }
Karsten Hopp 193f84
+ 	    ml_replace(i, (char_u *) PyString_AsString(pyret), 1);
Karsten Hopp 193f84
+ 	    changed();
Karsten Hopp 193f84
+ #ifdef SYNTAX_HL
Karsten Hopp 193f84
+ 	    syn_changed(i); /* recompute syntax hl. for this line */
Karsten Hopp 193f84
+ #endif
Karsten Hopp 193f84
+ 	}
Karsten Hopp 193f84
+ 	Py_XDECREF(pyret);
Karsten Hopp 193f84
+ 	PythonIO_Flush();
Karsten Hopp 193f84
+ 	PyGILState_Release(pygilstate);
Karsten Hopp 193f84
+     }
Karsten Hopp 193f84
+     pygilstate = PyGILState_Ensure();
Karsten Hopp 193f84
+ out:
Karsten Hopp 193f84
+     Py_DECREF(pyfunc);
Karsten Hopp 193f84
+     PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
Karsten Hopp 193f84
+     PyGILState_Release(pygilstate);
Karsten Hopp 193f84
+     if (status)
Karsten Hopp 193f84
+ 	return;
Karsten Hopp 193f84
+     check_cursor();
Karsten Hopp 193f84
+     update_curbuf(NOT_VALID);
Karsten Hopp 193f84
+ }
Karsten Hopp 193f84
+ 
Karsten Hopp 193f84
  /******************************************************
Karsten Hopp 193f84
   * 2. Python output stream: writes output via [e]msg().
Karsten Hopp 193f84
   */
Karsten Hopp 193f84
*** ../vim-7.3.965/src/if_python3.c	2013-05-17 16:18:27.000000000 +0200
Karsten Hopp 193f84
--- src/if_python3.c	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 76,82 ****
Karsten Hopp 193f84
  #else
Karsten Hopp 193f84
  # define CODEC_ERROR_HANDLER NULL
Karsten Hopp 193f84
  #endif
Karsten Hopp 193f84
- #define DOPY_FUNC "_vim_pydo"
Karsten Hopp 193f84
  
Karsten Hopp 193f84
  /* Python 3 does not support CObjects, always use Capsules */
Karsten Hopp 193f84
  #define PY_USE_CAPSULE
Karsten Hopp 193f84
--- 76,81 ----
Karsten Hopp 193f84
*** ../vim-7.3.965/src/proto/if_python.pro	2013-05-15 15:12:25.000000000 +0200
Karsten Hopp 193f84
--- src/proto/if_python.pro	2013-05-17 16:29:38.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 3,8 ****
Karsten Hopp 193f84
--- 3,9 ----
Karsten Hopp 193f84
  void python_end __ARGS((void));
Karsten Hopp 193f84
  int python_loaded __ARGS((void));
Karsten Hopp 193f84
  void ex_python __ARGS((exarg_T *eap));
Karsten Hopp 193f84
+ void ex_pydo __ARGS((exarg_T *eap));
Karsten Hopp 193f84
  void ex_pyfile __ARGS((exarg_T *eap));
Karsten Hopp 193f84
  void python_buffer_free __ARGS((buf_T *buf));
Karsten Hopp 193f84
  void python_window_free __ARGS((win_T *win));
Karsten Hopp 193f84
*** ../vim-7.3.965/src/version.c	2013-05-17 16:24:27.000000000 +0200
Karsten Hopp 193f84
--- src/version.c	2013-05-17 16:39:19.000000000 +0200
Karsten Hopp 193f84
***************
Karsten Hopp 193f84
*** 730,731 ****
Karsten Hopp 193f84
--- 730,733 ----
Karsten Hopp 193f84
  {   /* Add new patch number below this line */
Karsten Hopp 193f84
+ /**/
Karsten Hopp 193f84
+     966,
Karsten Hopp 193f84
  /**/
Karsten Hopp 193f84
Karsten Hopp 193f84
-- 
Karsten Hopp 193f84
A hamburger walks into a bar, and the bartender says: "I'm sorry,
Karsten Hopp 193f84
but we don't serve food here."
Karsten Hopp 193f84
Karsten Hopp 193f84
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 193f84
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 193f84
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 193f84
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///