forked from aniani/vim
updated for version 7.3.991
Problem: More can be shared by Python 2 and 3. Solution: Move more stuff to if_py_both. (ZyX)
This commit is contained in:
127
src/if_py_both.h
127
src/if_py_both.h
@@ -30,6 +30,9 @@ typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
|
|||||||
#define INVALID_WINDOW_VALUE ((win_T *)(-1))
|
#define INVALID_WINDOW_VALUE ((win_T *)(-1))
|
||||||
#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
|
#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
|
||||||
|
|
||||||
|
typedef void (*rangeinitializer)(void *);
|
||||||
|
typedef void (*runner)(const char *, void *, PyGILState_STATE *);
|
||||||
|
|
||||||
static int ConvertFromPyObject(PyObject *, typval_T *);
|
static int ConvertFromPyObject(PyObject *, typval_T *);
|
||||||
static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
|
static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
|
||||||
static PyObject *WindowNew(win_T *, tabpage_T *);
|
static PyObject *WindowNew(win_T *, tabpage_T *);
|
||||||
@@ -39,6 +42,8 @@ static PyObject *LineToString(const char *);
|
|||||||
static PyInt RangeStart;
|
static PyInt RangeStart;
|
||||||
static PyInt RangeEnd;
|
static PyInt RangeEnd;
|
||||||
|
|
||||||
|
static PyObject *globals;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* obtain a lock on the Vim data structures
|
* obtain a lock on the Vim data structures
|
||||||
*/
|
*/
|
||||||
@@ -1296,7 +1301,7 @@ FunctionDestructor(PyObject *self)
|
|||||||
FunctionObject *this = (FunctionObject *) (self);
|
FunctionObject *this = (FunctionObject *) (self);
|
||||||
|
|
||||||
func_unref(this->name);
|
func_unref(this->name);
|
||||||
PyMem_Del(this->name);
|
PyMem_Free(this->name);
|
||||||
|
|
||||||
DESTRUCTOR_FINISH(self);
|
DESTRUCTOR_FINISH(self);
|
||||||
}
|
}
|
||||||
@@ -3431,6 +3436,126 @@ CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_range_cmd(exarg_T *eap)
|
||||||
|
{
|
||||||
|
RangeStart = eap->line1;
|
||||||
|
RangeEnd = eap->line2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_range_eval(typval_T *rettv UNUSED)
|
||||||
|
{
|
||||||
|
RangeStart = (PyInt) curwin->w_cursor.lnum;
|
||||||
|
RangeEnd = RangeStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_cmd(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate UNUSED)
|
||||||
|
{
|
||||||
|
PyRun_SimpleString((char *) cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
|
||||||
|
static int code_hdr_len = 30;
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_do(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate)
|
||||||
|
{
|
||||||
|
PyInt lnum;
|
||||||
|
size_t len;
|
||||||
|
char *code;
|
||||||
|
int status;
|
||||||
|
PyObject *pyfunc, *pymain;
|
||||||
|
|
||||||
|
if (u_save(RangeStart - 1, RangeEnd + 1) != OK)
|
||||||
|
{
|
||||||
|
EMSG(_("cannot save undo information"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = code_hdr_len + STRLEN(cmd);
|
||||||
|
code = PyMem_New(char, len + 1);
|
||||||
|
memcpy(code, code_hdr, code_hdr_len);
|
||||||
|
STRCPY(code + code_hdr_len, cmd);
|
||||||
|
status = PyRun_SimpleString(code);
|
||||||
|
PyMem_Free(code);
|
||||||
|
|
||||||
|
if (status)
|
||||||
|
{
|
||||||
|
EMSG(_("failed to run the code"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = 0;
|
||||||
|
pymain = PyImport_AddModule("__main__");
|
||||||
|
pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
|
||||||
|
PyGILState_Release(*pygilstate);
|
||||||
|
|
||||||
|
for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
|
||||||
|
{
|
||||||
|
PyObject *line, *linenr, *ret;
|
||||||
|
|
||||||
|
*pygilstate = PyGILState_Ensure();
|
||||||
|
if (!(line = GetBufferLine(curbuf, lnum)))
|
||||||
|
goto err;
|
||||||
|
if (!(linenr = PyInt_FromLong((long) lnum)))
|
||||||
|
{
|
||||||
|
Py_DECREF(line);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
|
||||||
|
Py_DECREF(line);
|
||||||
|
Py_DECREF(linenr);
|
||||||
|
if (!ret)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (ret != Py_None)
|
||||||
|
if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
Py_XDECREF(ret);
|
||||||
|
PythonIO_Flush();
|
||||||
|
PyGILState_Release(*pygilstate);
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
err:
|
||||||
|
*pygilstate = PyGILState_Ensure();
|
||||||
|
PyErr_PrintEx(0);
|
||||||
|
PythonIO_Flush();
|
||||||
|
status = 1;
|
||||||
|
out:
|
||||||
|
if (!status)
|
||||||
|
*pygilstate = PyGILState_Ensure();
|
||||||
|
Py_DECREF(pyfunc);
|
||||||
|
PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
|
||||||
|
if (status)
|
||||||
|
return;
|
||||||
|
check_cursor();
|
||||||
|
update_curbuf(NOT_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
run_eval(const char *cmd, typval_T *rettv, PyGILState_STATE *pygilstate UNUSED)
|
||||||
|
{
|
||||||
|
PyObject *r;
|
||||||
|
|
||||||
|
r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
|
||||||
|
if (r == NULL)
|
||||||
|
{
|
||||||
|
if (PyErr_Occurred() && !msg_silent)
|
||||||
|
PyErr_PrintEx(0);
|
||||||
|
EMSG(_("E858: Eval did not return a valid python object"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ConvertFromPyObject(r, rettv) == -1)
|
||||||
|
EMSG(_("E859: Failed to convert returned python object to vim value"));
|
||||||
|
Py_DECREF(r);
|
||||||
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_ref_in_py(const int copyID)
|
set_ref_in_py(const int copyID)
|
||||||
{
|
{
|
||||||
|
142
src/if_python.c
142
src/if_python.c
@@ -659,8 +659,6 @@ static PyObject *FunctionGetattr(PyObject *, char *);
|
|||||||
* Internal function prototypes.
|
* Internal function prototypes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PyObject *globals;
|
|
||||||
|
|
||||||
static void PythonIO_Flush(void);
|
static void PythonIO_Flush(void);
|
||||||
static int PythonIO_Init(void);
|
static int PythonIO_Init(void);
|
||||||
static int PythonMod_Init(void);
|
static int PythonMod_Init(void);
|
||||||
@@ -828,7 +826,7 @@ fail:
|
|||||||
* External interface
|
* External interface
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv)
|
DoPyCommand(const char *cmd, rangeinitializer init_range, runner run, void *arg)
|
||||||
{
|
{
|
||||||
#ifndef PY_CAN_RECURSE
|
#ifndef PY_CAN_RECURSE
|
||||||
static int recursive = 0;
|
static int recursive = 0;
|
||||||
@@ -861,16 +859,8 @@ DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv)
|
|||||||
if (Python_Init())
|
if (Python_Init())
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
if (rettv == NULL)
|
init_range(arg);
|
||||||
{
|
|
||||||
RangeStart = eap->line1;
|
|
||||||
RangeEnd = eap->line2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RangeStart = (PyInt) curwin->w_cursor.lnum;
|
|
||||||
RangeEnd = RangeStart;
|
|
||||||
}
|
|
||||||
Python_Release_Vim(); /* leave vim */
|
Python_Release_Vim(); /* leave vim */
|
||||||
|
|
||||||
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
|
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
|
||||||
@@ -892,27 +882,7 @@ DoPythonCommand(exarg_T *eap, const char *cmd, typval_T *rettv)
|
|||||||
Python_RestoreThread(); /* enter python */
|
Python_RestoreThread(); /* enter python */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (rettv == NULL)
|
run((char *) cmd, arg, &pygilstate);
|
||||||
PyRun_SimpleString((char *)(cmd));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyObject *r;
|
|
||||||
|
|
||||||
r = PyRun_String((char *)(cmd), Py_eval_input, globals, globals);
|
|
||||||
if (r == NULL)
|
|
||||||
{
|
|
||||||
if (PyErr_Occurred() && !msg_silent)
|
|
||||||
PyErr_PrintEx(0);
|
|
||||||
EMSG(_("E858: Eval did not return a valid python object"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ConvertFromPyObject(r, rettv) == -1)
|
|
||||||
EMSG(_("E859: Failed to convert returned python object to vim value"));
|
|
||||||
Py_DECREF(r);
|
|
||||||
}
|
|
||||||
PyErr_Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef PY_CAN_RECURSE
|
#ifdef PY_CAN_RECURSE
|
||||||
PyGILState_Release(pygilstate);
|
PyGILState_Release(pygilstate);
|
||||||
@@ -952,10 +922,10 @@ ex_python(exarg_T *eap)
|
|||||||
script = script_get(eap, eap->arg);
|
script = script_get(eap, eap->arg);
|
||||||
if (!eap->skip)
|
if (!eap->skip)
|
||||||
{
|
{
|
||||||
if (script == NULL)
|
DoPyCommand(script == NULL ? (char *) eap->arg : (char *) script,
|
||||||
DoPythonCommand(eap, (char *)eap->arg, NULL);
|
(rangeinitializer) init_range_cmd,
|
||||||
else
|
(runner) run_cmd,
|
||||||
DoPythonCommand(eap, (char *)script, NULL);
|
(void *) eap);
|
||||||
}
|
}
|
||||||
vim_free(script);
|
vim_free(script);
|
||||||
}
|
}
|
||||||
@@ -1001,94 +971,19 @@ ex_pyfile(exarg_T *eap)
|
|||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
|
|
||||||
/* Execute the file */
|
/* Execute the file */
|
||||||
DoPythonCommand(eap, buffer, NULL);
|
DoPyCommand(buffer,
|
||||||
|
(rangeinitializer) init_range_cmd,
|
||||||
|
(runner) run_cmd,
|
||||||
|
(void *) eap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ex_pydo(exarg_T *eap)
|
ex_pydo(exarg_T *eap)
|
||||||
{
|
{
|
||||||
linenr_T i;
|
DoPyCommand((char *)eap->arg,
|
||||||
const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
|
(rangeinitializer) init_range_cmd,
|
||||||
const char *s = (const char *) eap->arg;
|
(runner)run_do,
|
||||||
size_t len;
|
(void *)eap);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
@@ -1525,7 +1420,10 @@ FunctionGetattr(PyObject *self, char *name)
|
|||||||
void
|
void
|
||||||
do_pyeval (char_u *str, typval_T *rettv)
|
do_pyeval (char_u *str, typval_T *rettv)
|
||||||
{
|
{
|
||||||
DoPythonCommand(NULL, (char *) str, rettv);
|
DoPyCommand((char *) str,
|
||||||
|
(rangeinitializer) init_range_eval,
|
||||||
|
(runner) run_eval,
|
||||||
|
(void *) rettv);
|
||||||
switch(rettv->v_type)
|
switch(rettv->v_type)
|
||||||
{
|
{
|
||||||
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
|
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
|
||||||
|
149
src/if_python3.c
149
src/if_python3.c
@@ -703,8 +703,6 @@ static struct PyModuleDef vimmodule;
|
|||||||
* Internal function prototypes.
|
* Internal function prototypes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static PyObject *globals;
|
|
||||||
|
|
||||||
static int PythonIO_Init(void);
|
static int PythonIO_Init(void);
|
||||||
static PyObject *Py3Init_vim(void);
|
static PyObject *Py3Init_vim(void);
|
||||||
|
|
||||||
@@ -827,7 +825,7 @@ fail:
|
|||||||
* External interface
|
* External interface
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
DoPy3Command(exarg_T *eap, const char *cmd, typval_T *rettv)
|
DoPyCommand(const char *cmd, rangeinitializer init_range, runner run, void *arg)
|
||||||
{
|
{
|
||||||
#if defined(MACOS) && !defined(MACOS_X_UNIX)
|
#if defined(MACOS) && !defined(MACOS_X_UNIX)
|
||||||
GrafPtr oldPort;
|
GrafPtr oldPort;
|
||||||
@@ -848,16 +846,8 @@ DoPy3Command(exarg_T *eap, const char *cmd, typval_T *rettv)
|
|||||||
if (Python3_Init())
|
if (Python3_Init())
|
||||||
goto theend;
|
goto theend;
|
||||||
|
|
||||||
if (rettv == NULL)
|
init_range(arg);
|
||||||
{
|
|
||||||
RangeStart = eap->line1;
|
|
||||||
RangeEnd = eap->line2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RangeStart = (PyInt) curwin->w_cursor.lnum;
|
|
||||||
RangeEnd = RangeStart;
|
|
||||||
}
|
|
||||||
Python_Release_Vim(); /* leave vim */
|
Python_Release_Vim(); /* leave vim */
|
||||||
|
|
||||||
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
|
#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
|
||||||
@@ -881,28 +871,8 @@ DoPy3Command(exarg_T *eap, const char *cmd, typval_T *rettv)
|
|||||||
(char *)ENC_OPT, CODEC_ERROR_HANDLER);
|
(char *)ENC_OPT, CODEC_ERROR_HANDLER);
|
||||||
cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER);
|
cmdbytes = PyUnicode_AsEncodedString(cmdstr, "utf-8", CODEC_ERROR_HANDLER);
|
||||||
Py_XDECREF(cmdstr);
|
Py_XDECREF(cmdstr);
|
||||||
if (rettv == NULL)
|
|
||||||
PyRun_SimpleString(PyBytes_AsString(cmdbytes));
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PyObject *r;
|
|
||||||
|
|
||||||
r = PyRun_String(PyBytes_AsString(cmdbytes), Py_eval_input,
|
run(PyBytes_AsString(cmdbytes), arg, &pygilstate);
|
||||||
globals, globals);
|
|
||||||
if (r == NULL)
|
|
||||||
{
|
|
||||||
if (PyErr_Occurred() && !msg_silent)
|
|
||||||
PyErr_PrintEx(0);
|
|
||||||
EMSG(_("E860: Eval did not return a valid python 3 object"));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ConvertFromPyObject(r, rettv) == -1)
|
|
||||||
EMSG(_("E861: Failed to convert returned python 3 object to vim value"));
|
|
||||||
Py_DECREF(r);
|
|
||||||
}
|
|
||||||
PyErr_Clear();
|
|
||||||
}
|
|
||||||
Py_XDECREF(cmdbytes);
|
Py_XDECREF(cmdbytes);
|
||||||
|
|
||||||
PyGILState_Release(pygilstate);
|
PyGILState_Release(pygilstate);
|
||||||
@@ -936,10 +906,10 @@ ex_py3(exarg_T *eap)
|
|||||||
script = script_get(eap, eap->arg);
|
script = script_get(eap, eap->arg);
|
||||||
if (!eap->skip)
|
if (!eap->skip)
|
||||||
{
|
{
|
||||||
if (script == NULL)
|
DoPyCommand(script == NULL ? (char *) eap->arg : (char *) script,
|
||||||
DoPy3Command(eap, (char *)eap->arg, NULL);
|
(rangeinitializer) init_range_cmd,
|
||||||
else
|
(runner) run_cmd,
|
||||||
DoPy3Command(eap, (char *)script, NULL);
|
(void *) eap);
|
||||||
}
|
}
|
||||||
vim_free(script);
|
vim_free(script);
|
||||||
}
|
}
|
||||||
@@ -1000,101 +970,19 @@ ex_py3file(exarg_T *eap)
|
|||||||
|
|
||||||
|
|
||||||
/* Execute the file */
|
/* Execute the file */
|
||||||
DoPy3Command(eap, buffer, NULL);
|
DoPyCommand(buffer,
|
||||||
|
(rangeinitializer) init_range_cmd,
|
||||||
|
(runner) run_cmd,
|
||||||
|
(void *) eap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ex_py3do(exarg_T *eap)
|
ex_py3do(exarg_T *eap)
|
||||||
{
|
{
|
||||||
linenr_T i;
|
DoPyCommand((char *)eap->arg,
|
||||||
const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
|
(rangeinitializer)init_range_cmd,
|
||||||
const char *s = (const char *) eap->arg;
|
(runner)run_do,
|
||||||
size_t len;
|
(void *)eap);
|
||||||
char *code;
|
|
||||||
int status;
|
|
||||||
PyObject *pyfunc, *pymain;
|
|
||||||
PyGILState_STATE pygilstate;
|
|
||||||
|
|
||||||
if (Python3_Init())
|
|
||||||
goto theend;
|
|
||||||
|
|
||||||
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, *pybytes;
|
|
||||||
|
|
||||||
line = (char *)ml_get(i);
|
|
||||||
pygilstate = PyGILState_Ensure();
|
|
||||||
pyline = PyUnicode_Decode(line, strlen(line),
|
|
||||||
(char *)ENC_OPT, CODEC_ERROR_HANDLER);
|
|
||||||
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 (!PyUnicode_Check(pyret))
|
|
||||||
{
|
|
||||||
EMSG(_("E863: return value must be an instance of str"));
|
|
||||||
Py_XDECREF(pyret);
|
|
||||||
status = 1;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
pybytes = PyUnicode_AsEncodedString(pyret,
|
|
||||||
(char *)ENC_OPT, CODEC_ERROR_HANDLER);
|
|
||||||
ml_replace(i, (char_u *) PyBytes_AsString(pybytes), 1);
|
|
||||||
Py_DECREF(pybytes);
|
|
||||||
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);
|
|
||||||
|
|
||||||
theend:
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
@@ -1790,7 +1678,10 @@ LineToString(const char *str)
|
|||||||
void
|
void
|
||||||
do_py3eval (char_u *str, typval_T *rettv)
|
do_py3eval (char_u *str, typval_T *rettv)
|
||||||
{
|
{
|
||||||
DoPy3Command(NULL, (char *) str, rettv);
|
DoPyCommand((char *) str,
|
||||||
|
(rangeinitializer) init_range_eval,
|
||||||
|
(runner) run_eval,
|
||||||
|
(void *) rettv);
|
||||||
switch(rettv->v_type)
|
switch(rettv->v_type)
|
||||||
{
|
{
|
||||||
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
|
case VAR_DICT: ++rettv->vval.v_dict->dv_refcount; break;
|
||||||
|
@@ -59,10 +59,10 @@ ll:[1]
|
|||||||
['c', 1]
|
['c', 1]
|
||||||
['d', ['e']]
|
['d', ['e']]
|
||||||
0.0
|
0.0
|
||||||
"\0": Vim(let):E861:
|
"\0": Vim(let):E859:
|
||||||
{"\0": 1}: Vim(let):E861:
|
{"\0": 1}: Vim(let):E859:
|
||||||
undefined_name: Vim(let):Trace
|
undefined_name: Vim(let):Trace
|
||||||
vim: Vim(let):E861:
|
vim: Vim(let):E859:
|
||||||
[1]
|
[1]
|
||||||
[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
|
[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
|
||||||
Abc
|
Abc
|
||||||
|
@@ -728,6 +728,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
991,
|
||||||
/**/
|
/**/
|
||||||
990,
|
990,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user