blob: 8185fc136f1a9790f94b6f32aa6fa2371b5cf2da [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
10 * Python extensions by Paul Moore.
11 * Changes for Unix by David Leonard.
12 *
13 * This consists of four parts:
14 * 1. Python interpreter main program
15 * 2. Python output stream: writes output via [e]msg().
16 * 3. Implementation of the Vim module for Python
17 * 4. Utility functions for handling the interface between Vim and Python.
18 */
19
20#include "vim.h"
21
Bram Moolenaar071d4272004-06-13 20:20:40 +000022#include <limits.h>
23
24/* Python.h defines _POSIX_THREADS itself (if needed) */
25#ifdef _POSIX_THREADS
26# undef _POSIX_THREADS
27#endif
28
Bram Moolenaar860cae12010-06-05 23:22:07 +020029#if defined(_WIN32) && defined(HAVE_FCNTL_H)
Bram Moolenaar071d4272004-06-13 20:20:40 +000030# undef HAVE_FCNTL_H
31#endif
32
33#ifdef _DEBUG
34# undef _DEBUG
35#endif
36
37#ifdef HAVE_STDARG_H
38# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
39#endif
Bram Moolenaarbe2c9ae2009-11-11 14:06:59 +000040#ifdef _POSIX_C_SOURCE
41# undef _POSIX_C_SOURCE /* pyconfig.h defines it as well. */
42#endif
43#ifdef _XOPEN_SOURCE
44# undef _XOPEN_SOURCE /* pyconfig.h defines it as well. */
45#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000046
Bram Moolenaar2c45e942008-06-04 11:35:26 +000047#define PY_SSIZE_T_CLEAN
48
Bram Moolenaar071d4272004-06-13 20:20:40 +000049#include <Python.h>
50#if defined(MACOS) && !defined(MACOS_X_UNIX)
51# include "macglue.h"
52# include <CodeFragments.h>
53#endif
54#undef main /* Defined in python.h - aargh */
55#undef HAVE_FCNTL_H /* Clash with os_win32.h */
56
57#if !defined(FEAT_PYTHON) && defined(PROTO)
58/* Use this to be able to generate prototypes without python being used. */
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +000059# define PyObject Py_ssize_t
60# define PyThreadState Py_ssize_t
61# define PyTypeObject Py_ssize_t
62struct PyMethodDef { Py_ssize_t a; };
63# define PySequenceMethods Py_ssize_t
Bram Moolenaar071d4272004-06-13 20:20:40 +000064#endif
65
Bram Moolenaar2c45e942008-06-04 11:35:26 +000066#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02050000
67# define PyInt Py_ssize_t
68# define PyInquiry lenfunc
69# define PyIntArgFunc ssizeargfunc
70# define PyIntIntArgFunc ssizessizeargfunc
71# define PyIntObjArgProc ssizeobjargproc
72# define PyIntIntObjArgProc ssizessizeobjargproc
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +000073# define Py_ssize_t_fmt "n"
Bram Moolenaar2c45e942008-06-04 11:35:26 +000074#else
75# define PyInt int
76# define PyInquiry inquiry
77# define PyIntArgFunc intargfunc
78# define PyIntIntArgFunc intintargfunc
79# define PyIntObjArgProc intobjargproc
80# define PyIntIntObjArgProc intintobjargproc
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +000081# define Py_ssize_t_fmt "i"
Bram Moolenaar2c45e942008-06-04 11:35:26 +000082#endif
83
Bram Moolenaar071d4272004-06-13 20:20:40 +000084/* Parser flags */
85#define single_input 256
86#define file_input 257
87#define eval_input 258
88
89#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x020300F0
90 /* Python 2.3: can invoke ":python" recursively. */
91# define PY_CAN_RECURSE
92#endif
93
94#if defined(DYNAMIC_PYTHON) || defined(PROTO)
95# ifndef DYNAMIC_PYTHON
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +000096# define HINSTANCE long_u /* for generating prototypes */
Bram Moolenaar071d4272004-06-13 20:20:40 +000097# endif
98
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020099#ifndef WIN3264
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200100# include <dlfcn.h>
101# define FARPROC void*
102# define HINSTANCE void*
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +0200103# define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200104# define close_dll dlclose
105# define symbol_from_dll dlsym
106#else
107# define load_dll LoadLibrary
108# define close_dll FreeLibrary
109# define symbol_from_dll GetProcAddress
110#endif
111
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000112/* This makes if_python.c compile without warnings against Python 2.5
113 * on Win32 and Win64. */
114#undef PyRun_SimpleString
115#undef PyArg_Parse
116#undef PyArg_ParseTuple
117#undef Py_BuildValue
118#undef Py_InitModule4
119#undef Py_InitModule4_64
120
Bram Moolenaar071d4272004-06-13 20:20:40 +0000121/*
122 * Wrapper defines
123 */
124# define PyArg_Parse dll_PyArg_Parse
125# define PyArg_ParseTuple dll_PyArg_ParseTuple
126# define PyDict_SetItemString dll_PyDict_SetItemString
127# define PyErr_BadArgument dll_PyErr_BadArgument
128# define PyErr_Clear dll_PyErr_Clear
129# define PyErr_NoMemory dll_PyErr_NoMemory
130# define PyErr_Occurred dll_PyErr_Occurred
131# define PyErr_SetNone dll_PyErr_SetNone
132# define PyErr_SetString dll_PyErr_SetString
133# define PyEval_InitThreads dll_PyEval_InitThreads
134# define PyEval_RestoreThread dll_PyEval_RestoreThread
135# define PyEval_SaveThread dll_PyEval_SaveThread
136# ifdef PY_CAN_RECURSE
137# define PyGILState_Ensure dll_PyGILState_Ensure
138# define PyGILState_Release dll_PyGILState_Release
139# endif
140# define PyInt_AsLong dll_PyInt_AsLong
141# define PyInt_FromLong dll_PyInt_FromLong
142# define PyInt_Type (*dll_PyInt_Type)
143# define PyList_GetItem dll_PyList_GetItem
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000144# define PyList_Append dll_PyList_Append
Bram Moolenaar071d4272004-06-13 20:20:40 +0000145# define PyList_New dll_PyList_New
146# define PyList_SetItem dll_PyList_SetItem
147# define PyList_Size dll_PyList_Size
148# define PyList_Type (*dll_PyList_Type)
149# define PyImport_ImportModule dll_PyImport_ImportModule
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000150# define PyDict_New dll_PyDict_New
Bram Moolenaar071d4272004-06-13 20:20:40 +0000151# define PyDict_GetItemString dll_PyDict_GetItemString
152# define PyModule_GetDict dll_PyModule_GetDict
153# define PyRun_SimpleString dll_PyRun_SimpleString
154# define PyString_AsString dll_PyString_AsString
155# define PyString_FromString dll_PyString_FromString
156# define PyString_FromStringAndSize dll_PyString_FromStringAndSize
157# define PyString_Size dll_PyString_Size
158# define PyString_Type (*dll_PyString_Type)
159# define PySys_SetObject dll_PySys_SetObject
160# define PySys_SetArgv dll_PySys_SetArgv
161# define PyType_Type (*dll_PyType_Type)
162# define Py_BuildValue dll_Py_BuildValue
163# define Py_FindMethod dll_Py_FindMethod
164# define Py_InitModule4 dll_Py_InitModule4
165# define Py_Initialize dll_Py_Initialize
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000166# define Py_Finalize dll_Py_Finalize
167# define Py_IsInitialized dll_Py_IsInitialized
Bram Moolenaar071d4272004-06-13 20:20:40 +0000168# define _PyObject_New dll__PyObject_New
169# define _Py_NoneStruct (*dll__Py_NoneStruct)
170# define PyObject_Init dll__PyObject_Init
171# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
172# define PyType_IsSubtype dll_PyType_IsSubtype
173# endif
174# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
175# define PyObject_Malloc dll_PyObject_Malloc
176# define PyObject_Free dll_PyObject_Free
177# endif
178
179/*
180 * Pointers for dynamic link
181 */
182static int(*dll_PyArg_Parse)(PyObject *, char *, ...);
183static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...);
184static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
185static int(*dll_PyErr_BadArgument)(void);
186static void(*dll_PyErr_Clear)(void);
187static PyObject*(*dll_PyErr_NoMemory)(void);
188static PyObject*(*dll_PyErr_Occurred)(void);
189static void(*dll_PyErr_SetNone)(PyObject *);
190static void(*dll_PyErr_SetString)(PyObject *, const char *);
191static void(*dll_PyEval_InitThreads)(void);
192static void(*dll_PyEval_RestoreThread)(PyThreadState *);
193static PyThreadState*(*dll_PyEval_SaveThread)(void);
194# ifdef PY_CAN_RECURSE
195static PyGILState_STATE (*dll_PyGILState_Ensure)(void);
196static void (*dll_PyGILState_Release)(PyGILState_STATE);
197#endif
198static long(*dll_PyInt_AsLong)(PyObject *);
199static PyObject*(*dll_PyInt_FromLong)(long);
200static PyTypeObject* dll_PyInt_Type;
Bram Moolenaar2c45e942008-06-04 11:35:26 +0000201static PyObject*(*dll_PyList_GetItem)(PyObject *, PyInt);
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000202static PyObject*(*dll_PyList_Append)(PyObject *, PyObject *);
Bram Moolenaar2c45e942008-06-04 11:35:26 +0000203static PyObject*(*dll_PyList_New)(PyInt size);
204static int(*dll_PyList_SetItem)(PyObject *, PyInt, PyObject *);
205static PyInt(*dll_PyList_Size)(PyObject *);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000206static PyTypeObject* dll_PyList_Type;
207static PyObject*(*dll_PyImport_ImportModule)(const char *);
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000208static PyObject*(*dll_PyDict_New)(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000209static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
210static PyObject*(*dll_PyModule_GetDict)(PyObject *);
211static int(*dll_PyRun_SimpleString)(char *);
212static char*(*dll_PyString_AsString)(PyObject *);
213static PyObject*(*dll_PyString_FromString)(const char *);
Bram Moolenaar2c45e942008-06-04 11:35:26 +0000214static PyObject*(*dll_PyString_FromStringAndSize)(const char *, PyInt);
215static PyInt(*dll_PyString_Size)(PyObject *);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000216static PyTypeObject* dll_PyString_Type;
217static int(*dll_PySys_SetObject)(char *, PyObject *);
218static int(*dll_PySys_SetArgv)(int, char **);
219static PyTypeObject* dll_PyType_Type;
220static PyObject*(*dll_Py_BuildValue)(char *, ...);
221static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *);
222static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int);
223static void(*dll_Py_Initialize)(void);
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000224static void(*dll_Py_Finalize)(void);
225static int(*dll_Py_IsInitialized)(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000226static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
227static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
228static PyObject* dll__Py_NoneStruct;
229# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
230static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
231# endif
232# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
233static void* (*dll_PyObject_Malloc)(size_t);
234static void (*dll_PyObject_Free)(void*);
235# endif
236
237static HINSTANCE hinstPython = 0; /* Instance of python.dll */
238
239/* Imported exception objects */
240static PyObject *imp_PyExc_AttributeError;
241static PyObject *imp_PyExc_IndexError;
242static PyObject *imp_PyExc_KeyboardInterrupt;
243static PyObject *imp_PyExc_TypeError;
244static PyObject *imp_PyExc_ValueError;
245
246# define PyExc_AttributeError imp_PyExc_AttributeError
247# define PyExc_IndexError imp_PyExc_IndexError
248# define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt
249# define PyExc_TypeError imp_PyExc_TypeError
250# define PyExc_ValueError imp_PyExc_ValueError
251
252/*
253 * Table of name to function pointer of python.
254 */
255# define PYTHON_PROC FARPROC
256static struct
257{
258 char *name;
259 PYTHON_PROC *ptr;
260} python_funcname_table[] =
261{
262 {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse},
263 {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple},
264 {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString},
265 {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
266 {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
267 {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory},
268 {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred},
269 {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
270 {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
271 {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
272 {"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
273 {"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
274# ifdef PY_CAN_RECURSE
275 {"PyGILState_Ensure", (PYTHON_PROC*)&dll_PyGILState_Ensure},
276 {"PyGILState_Release", (PYTHON_PROC*)&dll_PyGILState_Release},
277# endif
278 {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong},
279 {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong},
280 {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type},
281 {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000282 {"PyList_Append", (PYTHON_PROC*)&dll_PyList_Append},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000283 {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
284 {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
285 {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
286 {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type},
287 {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
288 {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
Bram Moolenaar0ac93792006-01-21 22:16:51 +0000289 {"PyDict_New", (PYTHON_PROC*)&dll_PyDict_New},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000290 {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
291 {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
292 {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
293 {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
294 {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize},
295 {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size},
296 {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type},
297 {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
298 {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
299 {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
300 {"Py_BuildValue", (PYTHON_PROC*)&dll_Py_BuildValue},
301 {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000302# if (PY_VERSION_HEX >= 0x02050000) && SIZEOF_SIZE_T != SIZEOF_INT
303 {"Py_InitModule4_64", (PYTHON_PROC*)&dll_Py_InitModule4},
304# else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000305 {"Py_InitModule4", (PYTHON_PROC*)&dll_Py_InitModule4},
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000306# endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000307 {"Py_Initialize", (PYTHON_PROC*)&dll_Py_Initialize},
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000308 {"Py_Finalize", (PYTHON_PROC*)&dll_Py_Finalize},
309 {"Py_IsInitialized", (PYTHON_PROC*)&dll_Py_IsInitialized},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000310 {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
311 {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
312 {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct},
313# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
314 {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype},
315# endif
316# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
317 {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc},
318 {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free},
319# endif
320 {"", NULL},
321};
322
323/*
324 * Free python.dll
325 */
326 static void
327end_dynamic_python(void)
328{
329 if (hinstPython)
330 {
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200331 close_dll(hinstPython);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000332 hinstPython = 0;
333 }
334}
335
336/*
337 * Load library and get all pointers.
338 * Parameter 'libname' provides name of DLL.
339 * Return OK or FAIL.
340 */
341 static int
342python_runtime_link_init(char *libname, int verbose)
343{
344 int i;
345
346 if (hinstPython)
347 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200348 hinstPython = load_dll(libname);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000349 if (!hinstPython)
350 {
351 if (verbose)
352 EMSG2(_(e_loadlib), libname);
353 return FAIL;
354 }
355
356 for (i = 0; python_funcname_table[i].ptr; ++i)
357 {
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200358 if ((*python_funcname_table[i].ptr = symbol_from_dll(hinstPython,
Bram Moolenaar071d4272004-06-13 20:20:40 +0000359 python_funcname_table[i].name)) == NULL)
360 {
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200361 close_dll(hinstPython);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000362 hinstPython = 0;
363 if (verbose)
364 EMSG2(_(e_loadfunc), python_funcname_table[i].name);
365 return FAIL;
366 }
367 }
368 return OK;
369}
370
371/*
372 * If python is enabled (there is installed python on Windows system) return
373 * TRUE, else FALSE.
374 */
375 int
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000376python_enabled(int verbose)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000377{
378 return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK;
379}
380
381/* Load the standard Python exceptions - don't import the symbols from the
382 * DLL, as this can cause errors (importing data symbols is not reliable).
383 */
384static void get_exceptions __ARGS((void));
385
386 static void
387get_exceptions()
388{
389 PyObject *exmod = PyImport_ImportModule("exceptions");
390 PyObject *exdict = PyModule_GetDict(exmod);
391 imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
392 imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
393 imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
394 imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
395 imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
396 Py_XINCREF(imp_PyExc_AttributeError);
397 Py_XINCREF(imp_PyExc_IndexError);
398 Py_XINCREF(imp_PyExc_KeyboardInterrupt);
399 Py_XINCREF(imp_PyExc_TypeError);
400 Py_XINCREF(imp_PyExc_ValueError);
401 Py_XDECREF(exmod);
402}
403#endif /* DYNAMIC_PYTHON */
404
405/******************************************************
406 * Internal function prototypes.
407 */
408
409static void DoPythonCommand(exarg_T *, const char *);
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000410static PyInt RangeStart;
411static PyInt RangeEnd;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000412
413static void PythonIO_Flush(void);
414static int PythonIO_Init(void);
415static int PythonMod_Init(void);
416
417/* Utility functions for the vim/python interface
418 * ----------------------------------------------
419 */
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000420static PyObject *GetBufferLine(buf_T *, PyInt);
Bram Moolenaar2c45e942008-06-04 11:35:26 +0000421static PyObject *GetBufferLineList(buf_T *, PyInt, PyInt);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000422
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000423static int SetBufferLine(buf_T *, PyInt, PyObject *, PyInt *);
424static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, PyInt *);
425static int InsertBufferLines(buf_T *, PyInt, PyObject *, PyInt *);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000426
427static PyObject *LineToString(const char *);
428static char *StringToLine(PyObject *);
429
430static int VimErrorCheck(void);
431
432#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
433
434/******************************************************
435 * 1. Python interpreter main program.
436 */
437
438static int initialised = 0;
439
440#if PYTHON_API_VERSION < 1007 /* Python 1.4 */
441typedef PyObject PyThreadState;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000442#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000443
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000444#ifdef PY_CAN_RECURSE
445static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
446#else
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000447static PyThreadState *saved_python_thread = NULL;
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000448#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000449
450/*
451 * Suspend a thread of the Python interpreter, other threads are allowed to
452 * run.
453 */
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000454 static void
455Python_SaveThread(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000456{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000457#ifdef PY_CAN_RECURSE
458 PyGILState_Release(pygilstate);
459#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000460 saved_python_thread = PyEval_SaveThread();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000461#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +0000462}
463
464/*
465 * Restore a thread of the Python interpreter, waits for other threads to
466 * block.
467 */
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000468 static void
469Python_RestoreThread(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000470{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000471#ifdef PY_CAN_RECURSE
472 pygilstate = PyGILState_Ensure();
473#else
Bram Moolenaar071d4272004-06-13 20:20:40 +0000474 PyEval_RestoreThread(saved_python_thread);
475 saved_python_thread = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000476#endif
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000477}
Bram Moolenaar071d4272004-06-13 20:20:40 +0000478
479/*
480 * obtain a lock on the Vim data structures
481 */
482static void Python_Lock_Vim(void)
483{
484}
485
486/*
487 * release a lock on the Vim data structures
488 */
489static void Python_Release_Vim(void)
490{
491}
492
493 void
494python_end()
495{
Bram Moolenaara5792f52005-11-23 21:25:05 +0000496 static int recurse = 0;
497
498 /* If a crash occurs while doing this, don't try again. */
499 if (recurse != 0)
500 return;
501
502 ++recurse;
503
Bram Moolenaar071d4272004-06-13 20:20:40 +0000504#ifdef DYNAMIC_PYTHON
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000505 if (hinstPython && Py_IsInitialized())
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000506 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000507 Python_RestoreThread(); /* enter python */
508 Py_Finalize();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000509 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000510 end_dynamic_python();
Bram Moolenaar0e21a3f2005-04-17 20:28:32 +0000511#else
512 if (Py_IsInitialized())
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000513 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +0000514 Python_RestoreThread(); /* enter python */
515 Py_Finalize();
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000516 }
Bram Moolenaar071d4272004-06-13 20:20:40 +0000517#endif
Bram Moolenaara5792f52005-11-23 21:25:05 +0000518
519 --recurse;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000520}
521
522 static int
523Python_Init(void)
524{
525 if (!initialised)
526 {
527#ifdef DYNAMIC_PYTHON
528 if (!python_enabled(TRUE))
529 {
530 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
531 goto fail;
532 }
533#endif
534
535#if !defined(MACOS) || defined(MACOS_X_UNIX)
536 Py_Initialize();
537#else
538 PyMac_Initialize();
539#endif
540 /* initialise threads */
541 PyEval_InitThreads();
542
543#ifdef DYNAMIC_PYTHON
544 get_exceptions();
545#endif
546
547 if (PythonIO_Init())
548 goto fail;
549
550 if (PythonMod_Init())
551 goto fail;
552
Bram Moolenaar9774ecc2008-11-20 10:04:53 +0000553 /* Remove the element from sys.path that was added because of our
554 * argv[0] value in PythonMod_Init(). Previously we used an empty
555 * string, but dependinding on the OS we then get an empty entry or
556 * the current directory in sys.path. */
557 PyRun_SimpleString("import sys; sys.path = filter(lambda x: x != '/must>not&exist', sys.path)");
558
Bram Moolenaar293ee4d2004-12-09 21:34:53 +0000559 /* the first python thread is vim's, release the lock */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000560 Python_SaveThread();
Bram Moolenaar071d4272004-06-13 20:20:40 +0000561
562 initialised = 1;
563 }
564
565 return 0;
566
567fail:
568 /* We call PythonIO_Flush() here to print any Python errors.
569 * This is OK, as it is possible to call this function even
570 * if PythonIO_Init() has not completed successfully (it will
571 * not do anything in this case).
572 */
573 PythonIO_Flush();
574 return -1;
575}
576
577/*
578 * External interface
579 */
580 static void
581DoPythonCommand(exarg_T *eap, const char *cmd)
582{
Bram Moolenaar9ba0eb82005-06-13 22:28:56 +0000583#ifndef PY_CAN_RECURSE
Bram Moolenaar071d4272004-06-13 20:20:40 +0000584 static int recursive = 0;
585#endif
586#if defined(MACOS) && !defined(MACOS_X_UNIX)
587 GrafPtr oldPort;
588#endif
589#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
590 char *saved_locale;
591#endif
592
593#ifndef PY_CAN_RECURSE
594 if (recursive)
595 {
596 EMSG(_("E659: Cannot invoke Python recursively"));
597 return;
598 }
599 ++recursive;
600#endif
601
602#if defined(MACOS) && !defined(MACOS_X_UNIX)
603 GetPort(&oldPort);
604 /* Check if the Python library is available */
605 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
606 goto theend;
607#endif
608 if (Python_Init())
609 goto theend;
610
611 RangeStart = eap->line1;
612 RangeEnd = eap->line2;
613 Python_Release_Vim(); /* leave vim */
614
615#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
616 /* Python only works properly when the LC_NUMERIC locale is "C". */
617 saved_locale = setlocale(LC_NUMERIC, NULL);
618 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
619 saved_locale = NULL;
620 else
621 {
622 /* Need to make a copy, value may change when setting new locale. */
623 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
624 (void)setlocale(LC_NUMERIC, "C");
625 }
626#endif
627
Bram Moolenaar071d4272004-06-13 20:20:40 +0000628 Python_RestoreThread(); /* enter python */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000629
630 PyRun_SimpleString((char *)(cmd));
631
Bram Moolenaar071d4272004-06-13 20:20:40 +0000632 Python_SaveThread(); /* leave python */
Bram Moolenaar071d4272004-06-13 20:20:40 +0000633
634#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
635 if (saved_locale != NULL)
636 {
637 (void)setlocale(LC_NUMERIC, saved_locale);
638 vim_free(saved_locale);
639 }
640#endif
641
642 Python_Lock_Vim(); /* enter vim */
643 PythonIO_Flush();
644#if defined(MACOS) && !defined(MACOS_X_UNIX)
645 SetPort(oldPort);
646#endif
647
648theend:
649#ifndef PY_CAN_RECURSE
650 --recursive;
651#endif
652 return; /* keeps lint happy */
653}
654
655/*
656 * ":python"
657 */
658 void
659ex_python(exarg_T *eap)
660{
661 char_u *script;
662
663 script = script_get(eap, eap->arg);
664 if (!eap->skip)
665 {
666 if (script == NULL)
667 DoPythonCommand(eap, (char *)eap->arg);
668 else
669 DoPythonCommand(eap, (char *)script);
670 }
671 vim_free(script);
672}
673
674#define BUFFER_SIZE 1024
675
676/*
677 * ":pyfile"
678 */
679 void
680ex_pyfile(exarg_T *eap)
681{
682 static char buffer[BUFFER_SIZE];
683 const char *file = (char *)eap->arg;
684 char *p;
685
686 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
687 * stdio file pointer, but Vim and the Python DLL are compiled with
688 * different options under Windows, meaning that stdio pointers aren't
689 * compatible between the two. Yuk.
690 *
691 * Put the string "execfile('file')" into buffer. But, we need to
692 * escape any backslashes or single quotes in the file name, so that
693 * Python won't mangle the file name.
694 */
695 strcpy(buffer, "execfile('");
696 p = buffer + 10; /* size of "execfile('" */
697
698 while (*file && p < buffer + (BUFFER_SIZE - 3))
699 {
700 if (*file == '\\' || *file == '\'')
701 *p++ = '\\';
702 *p++ = *file++;
703 }
704
705 /* If we didn't finish the file name, we hit a buffer overflow */
706 if (*file != '\0')
707 return;
708
709 /* Put in the terminating "')" and a null */
710 *p++ = '\'';
711 *p++ = ')';
712 *p++ = '\0';
713
714 /* Execute the file */
715 DoPythonCommand(eap, buffer);
716}
717
718/******************************************************
719 * 2. Python output stream: writes output via [e]msg().
720 */
721
722/* Implementation functions
723 */
724
725static PyObject *OutputGetattr(PyObject *, char *);
726static int OutputSetattr(PyObject *, char *, PyObject *);
727
728static PyObject *OutputWrite(PyObject *, PyObject *);
729static PyObject *OutputWritelines(PyObject *, PyObject *);
730
731typedef void (*writefn)(char_u *);
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000732static void writer(writefn fn, char_u *str, PyInt n);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000733
734/* Output object definition
735 */
736
737typedef struct
738{
739 PyObject_HEAD
740 long softspace;
741 long error;
742} OutputObject;
743
744static struct PyMethodDef OutputMethods[] = {
745 /* name, function, calling, documentation */
746 {"write", OutputWrite, 1, "" },
747 {"writelines", OutputWritelines, 1, "" },
748 { NULL, NULL, 0, NULL }
749};
750
751static PyTypeObject OutputType = {
752 PyObject_HEAD_INIT(0)
753 0,
754 "message",
755 sizeof(OutputObject),
756 0,
757
758 (destructor) 0,
759 (printfunc) 0,
760 (getattrfunc) OutputGetattr,
761 (setattrfunc) OutputSetattr,
762 (cmpfunc) 0,
763 (reprfunc) 0,
764
765 0, /* as number */
766 0, /* as sequence */
767 0, /* as mapping */
768
769 (hashfunc) 0,
770 (ternaryfunc) 0,
771 (reprfunc) 0
772};
773
774/*************/
775
776 static PyObject *
777OutputGetattr(PyObject *self, char *name)
778{
779 if (strcmp(name, "softspace") == 0)
780 return PyInt_FromLong(((OutputObject *)(self))->softspace);
781
782 return Py_FindMethod(OutputMethods, self, name);
783}
784
785 static int
786OutputSetattr(PyObject *self, char *name, PyObject *val)
787{
788 if (val == NULL) {
789 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
790 return -1;
791 }
792
793 if (strcmp(name, "softspace") == 0)
794 {
795 if (!PyInt_Check(val)) {
796 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
797 return -1;
798 }
799
800 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
801 return 0;
802 }
803
804 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
805 return -1;
806}
807
808/*************/
809
810 static PyObject *
811OutputWrite(PyObject *self, PyObject *args)
812{
813 int len;
814 char *str;
815 int error = ((OutputObject *)(self))->error;
816
817 if (!PyArg_ParseTuple(args, "s#", &str, &len))
818 return NULL;
819
820 Py_BEGIN_ALLOW_THREADS
821 Python_Lock_Vim();
822 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
823 Python_Release_Vim();
824 Py_END_ALLOW_THREADS
825
826 Py_INCREF(Py_None);
827 return Py_None;
828}
829
830 static PyObject *
831OutputWritelines(PyObject *self, PyObject *args)
832{
Bram Moolenaar2c45e942008-06-04 11:35:26 +0000833 PyInt n;
834 PyInt i;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000835 PyObject *list;
836 int error = ((OutputObject *)(self))->error;
837
838 if (!PyArg_ParseTuple(args, "O", &list))
839 return NULL;
840 Py_INCREF(list);
841
842 if (!PyList_Check(list)) {
843 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
844 Py_DECREF(list);
845 return NULL;
846 }
847
848 n = PyList_Size(list);
849
850 for (i = 0; i < n; ++i)
851 {
852 PyObject *line = PyList_GetItem(list, i);
853 char *str;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000854 PyInt len;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000855
856 if (!PyArg_Parse(line, "s#", &str, &len)) {
857 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
858 Py_DECREF(list);
859 return NULL;
860 }
861
862 Py_BEGIN_ALLOW_THREADS
863 Python_Lock_Vim();
864 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
865 Python_Release_Vim();
866 Py_END_ALLOW_THREADS
867 }
868
869 Py_DECREF(list);
870 Py_INCREF(Py_None);
871 return Py_None;
872}
873
874/* Output buffer management
875 */
876
877static char_u *buffer = NULL;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000878static PyInt buffer_len = 0;
879static PyInt buffer_size = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000880
881static writefn old_fn = NULL;
882
883 static void
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000884buffer_ensure(PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000885{
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000886 PyInt new_size;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000887 char_u *new_buffer;
888
889 if (n < buffer_size)
890 return;
891
892 new_size = buffer_size;
893 while (new_size < n)
894 new_size += 80;
895
896 if (new_size != buffer_size)
897 {
898 new_buffer = alloc((unsigned)new_size);
899 if (new_buffer == NULL)
900 return;
901
902 if (buffer)
903 {
904 memcpy(new_buffer, buffer, buffer_len);
905 vim_free(buffer);
906 }
907
908 buffer = new_buffer;
909 buffer_size = new_size;
910 }
911}
912
913 static void
914PythonIO_Flush(void)
915{
916 if (old_fn && buffer_len)
917 {
918 buffer[buffer_len] = 0;
919 old_fn(buffer);
920 }
921
922 buffer_len = 0;
923}
924
925 static void
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000926writer(writefn fn, char_u *str, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000927{
928 char_u *ptr;
929
930 if (fn != old_fn && old_fn != NULL)
931 PythonIO_Flush();
932
933 old_fn = fn;
934
935 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
936 {
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +0000937 PyInt len = ptr - str;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000938
939 buffer_ensure(buffer_len + len + 1);
940
941 memcpy(buffer + buffer_len, str, len);
942 buffer_len += len;
943 buffer[buffer_len] = 0;
944 fn(buffer);
945 str = ptr + 1;
946 n -= len + 1;
947 buffer_len = 0;
948 }
949
950 /* Put the remaining text into the buffer for later printing */
951 buffer_ensure(buffer_len + n + 1);
952 memcpy(buffer + buffer_len, str, n);
953 buffer_len += n;
954}
955
956/***************/
957
958static OutputObject Output =
959{
960 PyObject_HEAD_INIT(&OutputType)
961 0,
962 0
963};
964
965static OutputObject Error =
966{
967 PyObject_HEAD_INIT(&OutputType)
968 0,
969 1
970};
971
972 static int
973PythonIO_Init(void)
974{
975 /* Fixups... */
976 OutputType.ob_type = &PyType_Type;
977
Bram Moolenaar7df2d662005-01-25 22:18:08 +0000978 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
979 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000980
981 if (PyErr_Occurred())
982 {
983 EMSG(_("E264: Python: Error initialising I/O objects"));
984 return -1;
985 }
986
987 return 0;
988}
989
990/******************************************************
991 * 3. Implementation of the Vim module for Python
992 */
993
994/* Vim module - Implementation functions
995 * -------------------------------------
996 */
997
998static PyObject *VimError;
999
1000static PyObject *VimCommand(PyObject *, PyObject *);
1001static PyObject *VimEval(PyObject *, PyObject *);
1002
1003/* Window type - Implementation functions
1004 * --------------------------------------
1005 */
1006
1007typedef struct
1008{
1009 PyObject_HEAD
1010 win_T *win;
1011}
1012WindowObject;
1013
1014#define INVALID_WINDOW_VALUE ((win_T *)(-1))
1015
1016#define WindowType_Check(obj) ((obj)->ob_type == &WindowType)
1017
1018static PyObject *WindowNew(win_T *);
1019
1020static void WindowDestructor(PyObject *);
1021static PyObject *WindowGetattr(PyObject *, char *);
1022static int WindowSetattr(PyObject *, char *, PyObject *);
1023static PyObject *WindowRepr(PyObject *);
1024
1025/* Buffer type - Implementation functions
1026 * --------------------------------------
1027 */
1028
1029typedef struct
1030{
1031 PyObject_HEAD
1032 buf_T *buf;
1033}
1034BufferObject;
1035
1036#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
1037
1038#define BufferType_Check(obj) ((obj)->ob_type == &BufferType)
1039
1040static PyObject *BufferNew (buf_T *);
1041
1042static void BufferDestructor(PyObject *);
1043static PyObject *BufferGetattr(PyObject *, char *);
1044static PyObject *BufferRepr(PyObject *);
1045
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001046static PyInt BufferLength(PyObject *);
1047static PyObject *BufferItem(PyObject *, PyInt);
1048static PyObject *BufferSlice(PyObject *, PyInt, PyInt);
1049static PyInt BufferAssItem(PyObject *, PyInt, PyObject *);
1050static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001051
1052static PyObject *BufferAppend(PyObject *, PyObject *);
1053static PyObject *BufferMark(PyObject *, PyObject *);
1054static PyObject *BufferRange(PyObject *, PyObject *);
1055
1056/* Line range type - Implementation functions
1057 * --------------------------------------
1058 */
1059
1060typedef struct
1061{
1062 PyObject_HEAD
1063 BufferObject *buf;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001064 PyInt start;
1065 PyInt end;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001066}
1067RangeObject;
1068
1069#define RangeType_Check(obj) ((obj)->ob_type == &RangeType)
1070
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001071static PyObject *RangeNew(buf_T *, PyInt, PyInt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001072
1073static void RangeDestructor(PyObject *);
1074static PyObject *RangeGetattr(PyObject *, char *);
1075static PyObject *RangeRepr(PyObject *);
1076
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001077static PyInt RangeLength(PyObject *);
1078static PyObject *RangeItem(PyObject *, PyInt);
1079static PyObject *RangeSlice(PyObject *, PyInt, PyInt);
1080static PyInt RangeAssItem(PyObject *, PyInt, PyObject *);
1081static PyInt RangeAssSlice(PyObject *, PyInt, PyInt, PyObject *);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001082
1083static PyObject *RangeAppend(PyObject *, PyObject *);
1084
1085/* Window list type - Implementation functions
1086 * -------------------------------------------
1087 */
1088
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001089static PyInt WinListLength(PyObject *);
1090static PyObject *WinListItem(PyObject *, PyInt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001091
1092/* Buffer list type - Implementation functions
1093 * -------------------------------------------
1094 */
1095
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001096static PyInt BufListLength(PyObject *);
1097static PyObject *BufListItem(PyObject *, PyInt);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001098
1099/* Current objects type - Implementation functions
1100 * -----------------------------------------------
1101 */
1102
1103static PyObject *CurrentGetattr(PyObject *, char *);
1104static int CurrentSetattr(PyObject *, char *, PyObject *);
1105
1106/* Vim module - Definitions
1107 */
1108
1109static struct PyMethodDef VimMethods[] = {
1110 /* name, function, calling, documentation */
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001111 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
1112 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
Bram Moolenaar071d4272004-06-13 20:20:40 +00001113 { NULL, NULL, 0, NULL }
1114};
1115
1116/* Vim module - Implementation
1117 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001118 static PyObject *
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00001119VimCommand(PyObject *self UNUSED, PyObject *args)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001120{
1121 char *cmd;
1122 PyObject *result;
1123
1124 if (!PyArg_ParseTuple(args, "s", &cmd))
1125 return NULL;
1126
1127 PyErr_Clear();
1128
1129 Py_BEGIN_ALLOW_THREADS
1130 Python_Lock_Vim();
1131
1132 do_cmdline_cmd((char_u *)cmd);
1133 update_screen(VALID);
1134
1135 Python_Release_Vim();
1136 Py_END_ALLOW_THREADS
1137
1138 if (VimErrorCheck())
1139 result = NULL;
1140 else
1141 result = Py_None;
1142
1143 Py_XINCREF(result);
1144 return result;
1145}
1146
Bram Moolenaar01dd60c2008-07-24 14:24:48 +00001147#ifdef FEAT_EVAL
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001148/*
1149 * Function to translate a typval_T into a PyObject; this will recursively
1150 * translate lists/dictionaries into their Python equivalents.
1151 *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001152 * The depth parameter is to avoid infinite recursion, set it to 1 when
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001153 * you call VimToPython.
1154 */
1155 static PyObject *
1156VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
1157{
1158 PyObject *result;
1159 PyObject *newObj;
1160 char ptrBuf[NUMBUFLEN];
1161
1162 /* Avoid infinite recursion */
1163 if (depth > 100)
1164 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001165 Py_INCREF(Py_None);
1166 result = Py_None;
1167 return result;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001168 }
1169
1170 /* Check if we run into a recursive loop. The item must be in lookupDict
1171 * then and we can use it again. */
Bram Moolenaard72b3862009-01-13 17:11:05 +00001172 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
1173 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
1174 {
1175 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
Bram Moolenaarcc448b32010-07-14 16:52:17 +02001176 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
1177 : (long_u)our_tv->vval.v_dict);
Bram Moolenaard72b3862009-01-13 17:11:05 +00001178 result = PyDict_GetItemString(lookupDict, ptrBuf);
1179 if (result != NULL)
1180 {
1181 Py_INCREF(result);
1182 return result;
1183 }
1184 }
1185
1186 if (our_tv->v_type == VAR_STRING)
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001187 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001188 result = Py_BuildValue("s", our_tv->vval.v_string);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001189 }
1190 else if (our_tv->v_type == VAR_NUMBER)
1191 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001192 char buf[NUMBUFLEN];
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001193
1194 /* For backwards compatibility numbers are stored as strings. */
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001195 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
1196 result = Py_BuildValue("s", buf);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001197 }
Bram Moolenaar01dd60c2008-07-24 14:24:48 +00001198# ifdef FEAT_FLOAT
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001199 else if (our_tv->v_type == VAR_FLOAT)
1200 {
1201 char buf[NUMBUFLEN];
1202
1203 sprintf(buf, "%f", our_tv->vval.v_float);
1204 result = Py_BuildValue("s", buf);
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001205 }
Bram Moolenaar01dd60c2008-07-24 14:24:48 +00001206# endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001207 else if (our_tv->v_type == VAR_LIST)
1208 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001209 list_T *list = our_tv->vval.v_list;
1210 listitem_T *curr;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001211
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001212 result = PyList_New(0);
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001213
1214 if (list != NULL)
1215 {
Bram Moolenaard72b3862009-01-13 17:11:05 +00001216 PyDict_SetItemString(lookupDict, ptrBuf, result);
1217
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001218 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1219 {
1220 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1221 PyList_Append(result, newObj);
1222 Py_DECREF(newObj);
1223 }
1224 }
1225 }
1226 else if (our_tv->v_type == VAR_DICT)
1227 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001228 result = PyDict_New();
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001229
1230 if (our_tv->vval.v_dict != NULL)
1231 {
1232 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001233 long_u todo = ht->ht_used;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001234 hashitem_T *hi;
1235 dictitem_T *di;
1236
Bram Moolenaard72b3862009-01-13 17:11:05 +00001237 PyDict_SetItemString(lookupDict, ptrBuf, result);
1238
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001239 for (hi = ht->ht_array; todo > 0; ++hi)
1240 {
1241 if (!HASHITEM_EMPTY(hi))
1242 {
1243 --todo;
1244
1245 di = dict_lookup(hi);
1246 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1247 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1248 Py_DECREF(newObj);
1249 }
1250 }
1251 }
1252 }
1253 else
1254 {
Bram Moolenaarc9b4b052006-04-30 18:54:39 +00001255 Py_INCREF(Py_None);
1256 result = Py_None;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001257 }
1258
1259 return result;
1260}
Bram Moolenaar01dd60c2008-07-24 14:24:48 +00001261#endif
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001262
Bram Moolenaar071d4272004-06-13 20:20:40 +00001263 static PyObject *
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00001264VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001265{
1266#ifdef FEAT_EVAL
1267 char *expr;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001268 typval_T *our_tv;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001269 PyObject *result;
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001270 PyObject *lookup_dict;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001271
1272 if (!PyArg_ParseTuple(args, "s", &expr))
1273 return NULL;
1274
1275 Py_BEGIN_ALLOW_THREADS
1276 Python_Lock_Vim();
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001277 our_tv = eval_expr((char_u *)expr, NULL);
1278
Bram Moolenaar071d4272004-06-13 20:20:40 +00001279 Python_Release_Vim();
1280 Py_END_ALLOW_THREADS
1281
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001282 if (our_tv == NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001283 {
1284 PyErr_SetVim(_("invalid expression"));
1285 return NULL;
1286 }
1287
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001288 /* Convert the Vim type into a Python type. Create a dictionary that's
1289 * used to check for recursive loops. */
1290 lookup_dict = PyDict_New();
1291 result = VimToPython(our_tv, 1, lookup_dict);
1292 Py_DECREF(lookup_dict);
1293
Bram Moolenaar071d4272004-06-13 20:20:40 +00001294
1295 Py_BEGIN_ALLOW_THREADS
1296 Python_Lock_Vim();
Bram Moolenaarb71eaae2006-01-20 23:10:18 +00001297 free_tv(our_tv);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001298 Python_Release_Vim();
1299 Py_END_ALLOW_THREADS
1300
1301 return result;
1302#else
1303 PyErr_SetVim(_("expressions disabled at compile time"));
1304 return NULL;
1305#endif
1306}
1307
1308/* Common routines for buffers and line ranges
1309 * -------------------------------------------
1310 */
1311 static int
1312CheckBuffer(BufferObject *this)
1313{
1314 if (this->buf == INVALID_BUFFER_VALUE)
1315 {
1316 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1317 return -1;
1318 }
1319
1320 return 0;
1321}
1322
1323 static PyObject *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001324RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001325{
1326 if (CheckBuffer(self))
1327 return NULL;
1328
1329 if (n < 0 || n > end - start)
1330 {
1331 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1332 return NULL;
1333 }
1334
1335 return GetBufferLine(self->buf, n+start);
1336}
1337
1338 static PyObject *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001339RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001340{
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001341 PyInt size;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001342
1343 if (CheckBuffer(self))
1344 return NULL;
1345
1346 size = end - start + 1;
1347
1348 if (lo < 0)
1349 lo = 0;
1350 else if (lo > size)
1351 lo = size;
1352 if (hi < 0)
1353 hi = 0;
1354 if (hi < lo)
1355 hi = lo;
1356 else if (hi > size)
1357 hi = size;
1358
1359 return GetBufferLineList(self->buf, lo+start, hi+start);
1360}
1361
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001362 static PyInt
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001363RBAssItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001364{
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001365 PyInt len_change;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001366
1367 if (CheckBuffer(self))
1368 return -1;
1369
1370 if (n < 0 || n > end - start)
1371 {
1372 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1373 return -1;
1374 }
1375
1376 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1377 return -1;
1378
1379 if (new_end)
1380 *new_end = end + len_change;
1381
1382 return 0;
1383}
1384
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001385 static PyInt
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001386RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001387{
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001388 PyInt size;
1389 PyInt len_change;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001390
1391 /* Self must be a valid buffer */
1392 if (CheckBuffer(self))
1393 return -1;
1394
1395 /* Sort out the slice range */
1396 size = end - start + 1;
1397
1398 if (lo < 0)
1399 lo = 0;
1400 else if (lo > size)
1401 lo = size;
1402 if (hi < 0)
1403 hi = 0;
1404 if (hi < lo)
1405 hi = lo;
1406 else if (hi > size)
1407 hi = size;
1408
1409 if (SetBufferLineList(self->buf, lo+start, hi+start, val, &len_change) == FAIL)
1410 return -1;
1411
1412 if (new_end)
1413 *new_end = end + len_change;
1414
1415 return 0;
1416}
1417
1418 static PyObject *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001419RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001420{
1421 PyObject *lines;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001422 PyInt len_change;
1423 PyInt max;
1424 PyInt n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001425
1426 if (CheckBuffer(self))
1427 return NULL;
1428
1429 max = n = end - start + 1;
1430
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001431 if (!PyArg_ParseTuple(args, "O|" Py_ssize_t_fmt, &lines, &n))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001432 return NULL;
1433
1434 if (n < 0 || n > max)
1435 {
1436 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1437 return NULL;
1438 }
1439
1440 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1441 return NULL;
1442
1443 if (new_end)
1444 *new_end = end + len_change;
1445
1446 Py_INCREF(Py_None);
1447 return Py_None;
1448}
1449
1450
1451/* Buffer object - Definitions
1452 */
1453
1454static struct PyMethodDef BufferMethods[] = {
1455 /* name, function, calling, documentation */
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001456 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1457 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1458 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaar071d4272004-06-13 20:20:40 +00001459 { NULL, NULL, 0, NULL }
1460};
1461
1462static PySequenceMethods BufferAsSeq = {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001463 (PyInquiry) BufferLength, /* sq_length, len(x) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001464 (binaryfunc) 0, /* BufferConcat, */ /* sq_concat, x+y */
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001465 (PyIntArgFunc) 0, /* BufferRepeat, */ /* sq_repeat, x*n */
1466 (PyIntArgFunc) BufferItem, /* sq_item, x[i] */
1467 (PyIntIntArgFunc) BufferSlice, /* sq_slice, x[i:j] */
1468 (PyIntObjArgProc) BufferAssItem, /* sq_ass_item, x[i]=v */
1469 (PyIntIntObjArgProc) BufferAssSlice, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001470};
1471
1472static PyTypeObject BufferType = {
1473 PyObject_HEAD_INIT(0)
1474 0,
1475 "buffer",
1476 sizeof(BufferObject),
1477 0,
1478
1479 (destructor) BufferDestructor, /* tp_dealloc, refcount==0 */
1480 (printfunc) 0, /* tp_print, print x */
1481 (getattrfunc) BufferGetattr, /* tp_getattr, x.attr */
1482 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1483 (cmpfunc) 0, /* tp_compare, x>y */
1484 (reprfunc) BufferRepr, /* tp_repr, `x`, print x */
1485
1486 0, /* as number */
1487 &BufferAsSeq, /* as sequence */
1488 0, /* as mapping */
1489
1490 (hashfunc) 0, /* tp_hash, dict(x) */
1491 (ternaryfunc) 0, /* tp_call, x() */
1492 (reprfunc) 0, /* tp_str, str(x) */
1493};
1494
1495/* Buffer object - Implementation
1496 */
1497
1498 static PyObject *
1499BufferNew(buf_T *buf)
1500{
1501 /* We need to handle deletion of buffers underneath us.
Bram Moolenaare344bea2005-09-01 20:46:49 +00001502 * If we add a "b_python_ref" field to the buf_T structure,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001503 * then we can get at it in buf_freeall() in vim. We then
1504 * need to create only ONE Python object per buffer - if
1505 * we try to create a second, just INCREF the existing one
1506 * and return it. The (single) Python object referring to
Bram Moolenaare344bea2005-09-01 20:46:49 +00001507 * the buffer is stored in "b_python_ref".
Bram Moolenaar071d4272004-06-13 20:20:40 +00001508 * Question: what to do on a buf_freeall(). We'll probably
1509 * have to either delete the Python object (DECREF it to
1510 * zero - a bad idea, as it leaves dangling refs!) or
1511 * set the buf_T * value to an invalid value (-1?), which
1512 * means we need checks in all access functions... Bah.
1513 */
1514
1515 BufferObject *self;
1516
Bram Moolenaare344bea2005-09-01 20:46:49 +00001517 if (buf->b_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001518 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00001519 self = buf->b_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001520 Py_INCREF(self);
1521 }
1522 else
1523 {
1524 self = PyObject_NEW(BufferObject, &BufferType);
1525 if (self == NULL)
1526 return NULL;
1527 self->buf = buf;
Bram Moolenaare344bea2005-09-01 20:46:49 +00001528 buf->b_python_ref = self;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001529 }
1530
1531 return (PyObject *)(self);
1532}
1533
1534 static void
1535BufferDestructor(PyObject *self)
1536{
1537 BufferObject *this = (BufferObject *)(self);
1538
1539 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaare344bea2005-09-01 20:46:49 +00001540 this->buf->b_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001541
Bram Moolenaar658ada62006-10-03 13:02:36 +00001542 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001543}
1544
1545 static PyObject *
1546BufferGetattr(PyObject *self, char *name)
1547{
1548 BufferObject *this = (BufferObject *)(self);
1549
1550 if (CheckBuffer(this))
1551 return NULL;
1552
1553 if (strcmp(name, "name") == 0)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001554 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001555 else if (strcmp(name, "number") == 0)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001556 return Py_BuildValue(Py_ssize_t_fmt, this->buf->b_fnum);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001557 else if (strcmp(name,"__members__") == 0)
1558 return Py_BuildValue("[ss]", "name", "number");
1559 else
1560 return Py_FindMethod(BufferMethods, self, name);
1561}
1562
1563 static PyObject *
1564BufferRepr(PyObject *self)
1565{
Bram Moolenaar555b2802005-05-19 21:08:39 +00001566 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001567 BufferObject *this = (BufferObject *)(self);
1568
1569 if (this->buf == INVALID_BUFFER_VALUE)
1570 {
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001571 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001572 return PyString_FromString(repr);
1573 }
1574 else
1575 {
1576 char *name = (char *)this->buf->b_fname;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001577 PyInt len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001578
1579 if (name == NULL)
1580 name = "";
1581 len = strlen(name);
1582
1583 if (len > 35)
1584 name = name + (35 - len);
1585
Bram Moolenaar555b2802005-05-19 21:08:39 +00001586 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001587
1588 return PyString_FromString(repr);
1589 }
1590}
1591
1592/******************/
1593
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001594 static PyInt
Bram Moolenaar071d4272004-06-13 20:20:40 +00001595BufferLength(PyObject *self)
1596{
1597 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1598 if (CheckBuffer((BufferObject *)(self)))
1599 return -1; /* ??? */
1600
1601 return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
1602}
1603
1604 static PyObject *
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001605BufferItem(PyObject *self, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001606{
1607 return RBItem((BufferObject *)(self), n, 1,
1608 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1609}
1610
1611 static PyObject *
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001612BufferSlice(PyObject *self, PyInt lo, PyInt hi)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001613{
1614 return RBSlice((BufferObject *)(self), lo, hi, 1,
1615 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1616}
1617
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001618 static PyInt
1619BufferAssItem(PyObject *self, PyInt n, PyObject *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001620{
1621 return RBAssItem((BufferObject *)(self), n, val, 1,
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001622 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001623 NULL);
1624}
1625
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001626 static PyInt
1627BufferAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001628{
1629 return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001630 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001631 NULL);
1632}
1633
1634 static PyObject *
1635BufferAppend(PyObject *self, PyObject *args)
1636{
1637 return RBAppend((BufferObject *)(self), args, 1,
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001638 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001639 NULL);
1640}
1641
1642 static PyObject *
1643BufferMark(PyObject *self, PyObject *args)
1644{
1645 pos_T *posp;
1646 char mark;
1647 buf_T *curbuf_save;
1648
1649 if (CheckBuffer((BufferObject *)(self)))
1650 return NULL;
1651
1652 if (!PyArg_ParseTuple(args, "c", &mark))
1653 return NULL;
1654
1655 curbuf_save = curbuf;
1656 curbuf = ((BufferObject *)(self))->buf;
1657 posp = getmark(mark, FALSE);
1658 curbuf = curbuf_save;
1659
1660 if (posp == NULL)
1661 {
1662 PyErr_SetVim(_("invalid mark name"));
1663 return NULL;
1664 }
1665
1666 /* Ckeck for keyboard interrupt */
1667 if (VimErrorCheck())
1668 return NULL;
1669
1670 if (posp->lnum <= 0)
1671 {
1672 /* Or raise an error? */
1673 Py_INCREF(Py_None);
1674 return Py_None;
1675 }
1676
1677 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1678}
1679
1680 static PyObject *
1681BufferRange(PyObject *self, PyObject *args)
1682{
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001683 PyInt start;
1684 PyInt end;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001685
1686 if (CheckBuffer((BufferObject *)(self)))
1687 return NULL;
1688
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001689 if (!PyArg_ParseTuple(args, Py_ssize_t_fmt Py_ssize_t_fmt, &start, &end))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001690 return NULL;
1691
1692 return RangeNew(((BufferObject *)(self))->buf, start, end);
1693}
1694
1695/* Line range object - Definitions
1696 */
1697
1698static struct PyMethodDef RangeMethods[] = {
1699 /* name, function, calling, documentation */
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001700 {"append", RangeAppend, 1, "Append data to the Vim range" },
Bram Moolenaar071d4272004-06-13 20:20:40 +00001701 { NULL, NULL, 0, NULL }
1702};
1703
1704static PySequenceMethods RangeAsSeq = {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001705 (PyInquiry) RangeLength, /* sq_length, len(x) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001706 (binaryfunc) 0, /* RangeConcat, */ /* sq_concat, x+y */
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001707 (PyIntArgFunc) 0, /* RangeRepeat, */ /* sq_repeat, x*n */
1708 (PyIntArgFunc) RangeItem, /* sq_item, x[i] */
1709 (PyIntIntArgFunc) RangeSlice, /* sq_slice, x[i:j] */
1710 (PyIntObjArgProc) RangeAssItem, /* sq_ass_item, x[i]=v */
1711 (PyIntIntObjArgProc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001712};
1713
1714static PyTypeObject RangeType = {
1715 PyObject_HEAD_INIT(0)
1716 0,
1717 "range",
1718 sizeof(RangeObject),
1719 0,
1720
1721 (destructor) RangeDestructor, /* tp_dealloc, refcount==0 */
1722 (printfunc) 0, /* tp_print, print x */
1723 (getattrfunc) RangeGetattr, /* tp_getattr, x.attr */
1724 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1725 (cmpfunc) 0, /* tp_compare, x>y */
1726 (reprfunc) RangeRepr, /* tp_repr, `x`, print x */
1727
1728 0, /* as number */
1729 &RangeAsSeq, /* as sequence */
1730 0, /* as mapping */
1731
1732 (hashfunc) 0, /* tp_hash, dict(x) */
1733 (ternaryfunc) 0, /* tp_call, x() */
1734 (reprfunc) 0, /* tp_str, str(x) */
1735};
1736
1737/* Line range object - Implementation
1738 */
1739
1740 static PyObject *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001741RangeNew(buf_T *buf, PyInt start, PyInt end)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001742{
1743 BufferObject *bufr;
1744 RangeObject *self;
1745 self = PyObject_NEW(RangeObject, &RangeType);
1746 if (self == NULL)
1747 return NULL;
1748
1749 bufr = (BufferObject *)BufferNew(buf);
1750 if (bufr == NULL)
1751 {
Bram Moolenaar658ada62006-10-03 13:02:36 +00001752 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001753 return NULL;
1754 }
1755 Py_INCREF(bufr);
1756
1757 self->buf = bufr;
1758 self->start = start;
1759 self->end = end;
1760
1761 return (PyObject *)(self);
1762}
1763
1764 static void
1765RangeDestructor(PyObject *self)
1766{
1767 Py_DECREF(((RangeObject *)(self))->buf);
Bram Moolenaar658ada62006-10-03 13:02:36 +00001768 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001769}
1770
1771 static PyObject *
1772RangeGetattr(PyObject *self, char *name)
1773{
1774 if (strcmp(name, "start") == 0)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001775 return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->start - 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001776 else if (strcmp(name, "end") == 0)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001777 return Py_BuildValue(Py_ssize_t_fmt, ((RangeObject *)(self))->end - 1);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001778 else
1779 return Py_FindMethod(RangeMethods, self, name);
1780}
1781
1782 static PyObject *
1783RangeRepr(PyObject *self)
1784{
Bram Moolenaar555b2802005-05-19 21:08:39 +00001785 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00001786 RangeObject *this = (RangeObject *)(self);
1787
1788 if (this->buf->buf == INVALID_BUFFER_VALUE)
1789 {
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001790 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1791 (self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001792 return PyString_FromString(repr);
1793 }
1794 else
1795 {
1796 char *name = (char *)this->buf->buf->b_fname;
1797 int len;
1798
1799 if (name == NULL)
1800 name = "";
Bram Moolenaarc236c162008-07-13 17:41:49 +00001801 len = (int)strlen(name);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001802
1803 if (len > 45)
1804 name = name + (45 - len);
1805
Bram Moolenaar555b2802005-05-19 21:08:39 +00001806 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
Bram Moolenaar071d4272004-06-13 20:20:40 +00001807 len > 45 ? "..." : "", name,
1808 this->start, this->end);
1809
1810 return PyString_FromString(repr);
1811 }
1812}
1813
1814/****************/
1815
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001816 static PyInt
Bram Moolenaar071d4272004-06-13 20:20:40 +00001817RangeLength(PyObject *self)
1818{
1819 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1820 if (CheckBuffer(((RangeObject *)(self))->buf))
1821 return -1; /* ??? */
1822
1823 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1824}
1825
1826 static PyObject *
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001827RangeItem(PyObject *self, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001828{
1829 return RBItem(((RangeObject *)(self))->buf, n,
1830 ((RangeObject *)(self))->start,
1831 ((RangeObject *)(self))->end);
1832}
1833
1834 static PyObject *
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001835RangeSlice(PyObject *self, PyInt lo, PyInt hi)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001836{
1837 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1838 ((RangeObject *)(self))->start,
1839 ((RangeObject *)(self))->end);
1840}
1841
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001842 static PyInt
1843RangeAssItem(PyObject *self, PyInt n, PyObject *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001844{
1845 return RBAssItem(((RangeObject *)(self))->buf, n, val,
1846 ((RangeObject *)(self))->start,
1847 ((RangeObject *)(self))->end,
1848 &((RangeObject *)(self))->end);
1849}
1850
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001851 static PyInt
1852RangeAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001853{
1854 return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
1855 ((RangeObject *)(self))->start,
1856 ((RangeObject *)(self))->end,
1857 &((RangeObject *)(self))->end);
1858}
1859
1860 static PyObject *
1861RangeAppend(PyObject *self, PyObject *args)
1862{
1863 return RBAppend(((RangeObject *)(self))->buf, args,
1864 ((RangeObject *)(self))->start,
1865 ((RangeObject *)(self))->end,
1866 &((RangeObject *)(self))->end);
1867}
1868
1869/* Buffer list object - Definitions
1870 */
1871
1872typedef struct
1873{
1874 PyObject_HEAD
1875}
1876BufListObject;
1877
1878static PySequenceMethods BufListAsSeq = {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001879 (PyInquiry) BufListLength, /* sq_length, len(x) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001880 (binaryfunc) 0, /* sq_concat, x+y */
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001881 (PyIntArgFunc) 0, /* sq_repeat, x*n */
1882 (PyIntArgFunc) BufListItem, /* sq_item, x[i] */
1883 (PyIntIntArgFunc) 0, /* sq_slice, x[i:j] */
1884 (PyIntObjArgProc) 0, /* sq_ass_item, x[i]=v */
1885 (PyIntIntObjArgProc) 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001886};
1887
1888static PyTypeObject BufListType = {
1889 PyObject_HEAD_INIT(0)
1890 0,
1891 "buffer list",
1892 sizeof(BufListObject),
1893 0,
1894
1895 (destructor) 0, /* tp_dealloc, refcount==0 */
1896 (printfunc) 0, /* tp_print, print x */
1897 (getattrfunc) 0, /* tp_getattr, x.attr */
1898 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1899 (cmpfunc) 0, /* tp_compare, x>y */
1900 (reprfunc) 0, /* tp_repr, `x`, print x */
1901
1902 0, /* as number */
1903 &BufListAsSeq, /* as sequence */
1904 0, /* as mapping */
1905
1906 (hashfunc) 0, /* tp_hash, dict(x) */
1907 (ternaryfunc) 0, /* tp_call, x() */
1908 (reprfunc) 0, /* tp_str, str(x) */
1909};
1910
1911/* Buffer list object - Implementation
1912 */
1913
Bram Moolenaar2c45e942008-06-04 11:35:26 +00001914 static PyInt
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00001915BufListLength(PyObject *self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001916{
1917 buf_T *b = firstbuf;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00001918 PyInt n = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001919
1920 while (b)
1921 {
1922 ++n;
1923 b = b->b_next;
1924 }
1925
1926 return n;
1927}
1928
Bram Moolenaar071d4272004-06-13 20:20:40 +00001929 static PyObject *
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00001930BufListItem(PyObject *self UNUSED, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001931{
1932 buf_T *b;
1933
1934 for (b = firstbuf; b; b = b->b_next, --n)
1935 {
1936 if (n == 0)
1937 return BufferNew(b);
1938 }
1939
1940 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1941 return NULL;
1942}
1943
1944/* Window object - Definitions
1945 */
1946
1947static struct PyMethodDef WindowMethods[] = {
1948 /* name, function, calling, documentation */
1949 { NULL, NULL, 0, NULL }
1950};
1951
1952static PyTypeObject WindowType = {
1953 PyObject_HEAD_INIT(0)
1954 0,
1955 "window",
1956 sizeof(WindowObject),
1957 0,
1958
1959 (destructor) WindowDestructor, /* tp_dealloc, refcount==0 */
1960 (printfunc) 0, /* tp_print, print x */
1961 (getattrfunc) WindowGetattr, /* tp_getattr, x.attr */
1962 (setattrfunc) WindowSetattr, /* tp_setattr, x.attr=v */
1963 (cmpfunc) 0, /* tp_compare, x>y */
1964 (reprfunc) WindowRepr, /* tp_repr, `x`, print x */
1965
1966 0, /* as number */
1967 0, /* as sequence */
1968 0, /* as mapping */
1969
1970 (hashfunc) 0, /* tp_hash, dict(x) */
1971 (ternaryfunc) 0, /* tp_call, x() */
1972 (reprfunc) 0, /* tp_str, str(x) */
1973};
1974
1975/* Window object - Implementation
1976 */
1977
1978 static PyObject *
1979WindowNew(win_T *win)
1980{
1981 /* We need to handle deletion of windows underneath us.
Bram Moolenaare344bea2005-09-01 20:46:49 +00001982 * If we add a "w_python_ref" field to the win_T structure,
Bram Moolenaar071d4272004-06-13 20:20:40 +00001983 * then we can get at it in win_free() in vim. We then
1984 * need to create only ONE Python object per window - if
1985 * we try to create a second, just INCREF the existing one
1986 * and return it. The (single) Python object referring to
Bram Moolenaare344bea2005-09-01 20:46:49 +00001987 * the window is stored in "w_python_ref".
Bram Moolenaar071d4272004-06-13 20:20:40 +00001988 * On a win_free() we set the Python object's win_T* field
1989 * to an invalid value. We trap all uses of a window
1990 * object, and reject them if the win_T* field is invalid.
1991 */
1992
1993 WindowObject *self;
1994
Bram Moolenaare344bea2005-09-01 20:46:49 +00001995 if (win->w_python_ref)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001996 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00001997 self = win->w_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001998 Py_INCREF(self);
1999 }
2000 else
2001 {
2002 self = PyObject_NEW(WindowObject, &WindowType);
2003 if (self == NULL)
2004 return NULL;
2005 self->win = win;
Bram Moolenaare344bea2005-09-01 20:46:49 +00002006 win->w_python_ref = self;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002007 }
2008
2009 return (PyObject *)(self);
2010}
2011
2012 static void
2013WindowDestructor(PyObject *self)
2014{
2015 WindowObject *this = (WindowObject *)(self);
2016
2017 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaare344bea2005-09-01 20:46:49 +00002018 this->win->w_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002019
Bram Moolenaar658ada62006-10-03 13:02:36 +00002020 Py_DECREF(self);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002021}
2022
2023 static int
2024CheckWindow(WindowObject *this)
2025{
2026 if (this->win == INVALID_WINDOW_VALUE)
2027 {
2028 PyErr_SetVim(_("attempt to refer to deleted window"));
2029 return -1;
2030 }
2031
2032 return 0;
2033}
2034
2035 static PyObject *
2036WindowGetattr(PyObject *self, char *name)
2037{
2038 WindowObject *this = (WindowObject *)(self);
2039
2040 if (CheckWindow(this))
2041 return NULL;
2042
2043 if (strcmp(name, "buffer") == 0)
2044 return (PyObject *)BufferNew(this->win->w_buffer);
2045 else if (strcmp(name, "cursor") == 0)
2046 {
2047 pos_T *pos = &this->win->w_cursor;
2048
2049 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2050 }
2051 else if (strcmp(name, "height") == 0)
2052 return Py_BuildValue("l", (long)(this->win->w_height));
2053#ifdef FEAT_VERTSPLIT
2054 else if (strcmp(name, "width") == 0)
2055 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
2056#endif
2057 else if (strcmp(name,"__members__") == 0)
2058 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
2059 else
2060 return Py_FindMethod(WindowMethods, self, name);
2061}
2062
2063 static int
2064WindowSetattr(PyObject *self, char *name, PyObject *val)
2065{
2066 WindowObject *this = (WindowObject *)(self);
2067
2068 if (CheckWindow(this))
2069 return -1;
2070
2071 if (strcmp(name, "buffer") == 0)
2072 {
2073 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2074 return -1;
2075 }
2076 else if (strcmp(name, "cursor") == 0)
2077 {
2078 long lnum;
2079 long col;
Bram Moolenaarbadfde12009-11-03 10:43:27 +00002080 long len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002081
2082 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2083 return -1;
2084
2085 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
2086 {
2087 PyErr_SetVim(_("cursor position outside buffer"));
2088 return -1;
2089 }
2090
2091 /* Check for keyboard interrupts */
2092 if (VimErrorCheck())
2093 return -1;
2094
Bram Moolenaarbadfde12009-11-03 10:43:27 +00002095 /* When column is out of range silently correct it. */
Bram Moolenaar8b9c05f2010-03-02 17:54:33 +01002096 len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE));
Bram Moolenaarbadfde12009-11-03 10:43:27 +00002097 if (col > len)
2098 col = len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002099
2100 this->win->w_cursor.lnum = lnum;
2101 this->win->w_cursor.col = col;
Bram Moolenaarbadfde12009-11-03 10:43:27 +00002102#ifdef FEAT_VIRTUALEDIT
2103 this->win->w_cursor.coladd = 0;
2104#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00002105 update_screen(VALID);
2106
2107 return 0;
2108 }
2109 else if (strcmp(name, "height") == 0)
2110 {
2111 int height;
2112 win_T *savewin;
2113
2114 if (!PyArg_Parse(val, "i", &height))
2115 return -1;
2116
2117#ifdef FEAT_GUI
2118 need_mouse_correct = TRUE;
2119#endif
2120 savewin = curwin;
2121 curwin = this->win;
2122 win_setheight(height);
2123 curwin = savewin;
2124
2125 /* Check for keyboard interrupts */
2126 if (VimErrorCheck())
2127 return -1;
2128
2129 return 0;
2130 }
2131#ifdef FEAT_VERTSPLIT
2132 else if (strcmp(name, "width") == 0)
2133 {
2134 int width;
2135 win_T *savewin;
2136
2137 if (!PyArg_Parse(val, "i", &width))
2138 return -1;
2139
2140#ifdef FEAT_GUI
2141 need_mouse_correct = TRUE;
2142#endif
2143 savewin = curwin;
2144 curwin = this->win;
2145 win_setwidth(width);
2146 curwin = savewin;
2147
2148 /* Check for keyboard interrupts */
2149 if (VimErrorCheck())
2150 return -1;
2151
2152 return 0;
2153 }
2154#endif
2155 else
2156 {
2157 PyErr_SetString(PyExc_AttributeError, name);
2158 return -1;
2159 }
2160}
2161
2162 static PyObject *
2163WindowRepr(PyObject *self)
2164{
Bram Moolenaar555b2802005-05-19 21:08:39 +00002165 static char repr[100];
Bram Moolenaar071d4272004-06-13 20:20:40 +00002166 WindowObject *this = (WindowObject *)(self);
2167
2168 if (this->win == INVALID_WINDOW_VALUE)
2169 {
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002170 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002171 return PyString_FromString(repr);
2172 }
2173 else
2174 {
2175 int i = 0;
2176 win_T *w;
2177
2178 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
2179 ++i;
2180
2181 if (w == NULL)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002182 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2183 (self));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002184 else
Bram Moolenaar555b2802005-05-19 21:08:39 +00002185 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002186
2187 return PyString_FromString(repr);
2188 }
2189}
2190
2191/* Window list object - Definitions
2192 */
2193
2194typedef struct
2195{
2196 PyObject_HEAD
2197}
2198WinListObject;
2199
2200static PySequenceMethods WinListAsSeq = {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002201 (PyInquiry) WinListLength, /* sq_length, len(x) */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002202 (binaryfunc) 0, /* sq_concat, x+y */
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002203 (PyIntArgFunc) 0, /* sq_repeat, x*n */
2204 (PyIntArgFunc) WinListItem, /* sq_item, x[i] */
2205 (PyIntIntArgFunc) 0, /* sq_slice, x[i:j] */
2206 (PyIntObjArgProc) 0, /* sq_ass_item, x[i]=v */
2207 (PyIntIntObjArgProc) 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002208};
2209
2210static PyTypeObject WinListType = {
2211 PyObject_HEAD_INIT(0)
2212 0,
2213 "window list",
2214 sizeof(WinListObject),
2215 0,
2216
2217 (destructor) 0, /* tp_dealloc, refcount==0 */
2218 (printfunc) 0, /* tp_print, print x */
2219 (getattrfunc) 0, /* tp_getattr, x.attr */
2220 (setattrfunc) 0, /* tp_setattr, x.attr=v */
2221 (cmpfunc) 0, /* tp_compare, x>y */
2222 (reprfunc) 0, /* tp_repr, `x`, print x */
2223
2224 0, /* as number */
2225 &WinListAsSeq, /* as sequence */
2226 0, /* as mapping */
2227
2228 (hashfunc) 0, /* tp_hash, dict(x) */
2229 (ternaryfunc) 0, /* tp_call, x() */
2230 (reprfunc) 0, /* tp_str, str(x) */
2231};
2232
2233/* Window list object - Implementation
2234 */
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002235 static PyInt
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00002236WinListLength(PyObject *self UNUSED)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002237{
2238 win_T *w = firstwin;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002239 PyInt n = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002240
Bram Moolenaarf740b292006-02-16 22:11:02 +00002241 while (w != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002242 {
2243 ++n;
2244 w = W_NEXT(w);
2245 }
2246
2247 return n;
2248}
2249
Bram Moolenaar071d4272004-06-13 20:20:40 +00002250 static PyObject *
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00002251WinListItem(PyObject *self UNUSED, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002252{
2253 win_T *w;
2254
Bram Moolenaarf740b292006-02-16 22:11:02 +00002255 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002256 if (n == 0)
2257 return WindowNew(w);
2258
2259 PyErr_SetString(PyExc_IndexError, _("no such window"));
2260 return NULL;
2261}
2262
2263/* Current items object - Definitions
2264 */
2265
2266typedef struct
2267{
2268 PyObject_HEAD
2269}
2270CurrentObject;
2271
2272static PyTypeObject CurrentType = {
2273 PyObject_HEAD_INIT(0)
2274 0,
2275 "current data",
2276 sizeof(CurrentObject),
2277 0,
2278
2279 (destructor) 0, /* tp_dealloc, refcount==0 */
2280 (printfunc) 0, /* tp_print, print x */
2281 (getattrfunc) CurrentGetattr, /* tp_getattr, x.attr */
2282 (setattrfunc) CurrentSetattr, /* tp_setattr, x.attr=v */
2283 (cmpfunc) 0, /* tp_compare, x>y */
2284 (reprfunc) 0, /* tp_repr, `x`, print x */
2285
2286 0, /* as number */
2287 0, /* as sequence */
2288 0, /* as mapping */
2289
2290 (hashfunc) 0, /* tp_hash, dict(x) */
2291 (ternaryfunc) 0, /* tp_call, x() */
2292 (reprfunc) 0, /* tp_str, str(x) */
2293};
2294
2295/* Current items object - Implementation
2296 */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002297 static PyObject *
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00002298CurrentGetattr(PyObject *self UNUSED, char *name)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002299{
2300 if (strcmp(name, "buffer") == 0)
2301 return (PyObject *)BufferNew(curbuf);
2302 else if (strcmp(name, "window") == 0)
2303 return (PyObject *)WindowNew(curwin);
2304 else if (strcmp(name, "line") == 0)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002305 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002306 else if (strcmp(name, "range") == 0)
2307 return RangeNew(curbuf, RangeStart, RangeEnd);
2308 else if (strcmp(name,"__members__") == 0)
2309 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
2310 else
2311 {
2312 PyErr_SetString(PyExc_AttributeError, name);
2313 return NULL;
2314 }
2315}
2316
Bram Moolenaar071d4272004-06-13 20:20:40 +00002317 static int
Bram Moolenaar4bdbbf72009-05-21 21:27:43 +00002318CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002319{
2320 if (strcmp(name, "line") == 0)
2321 {
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002322 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002323 return -1;
2324
2325 return 0;
2326 }
2327 else
2328 {
2329 PyErr_SetString(PyExc_AttributeError, name);
2330 return -1;
2331 }
2332}
2333
2334/* External interface
2335 */
2336
2337 void
2338python_buffer_free(buf_T *buf)
2339{
Bram Moolenaare344bea2005-09-01 20:46:49 +00002340 if (buf->b_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002341 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00002342 BufferObject *bp = buf->b_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002343 bp->buf = INVALID_BUFFER_VALUE;
Bram Moolenaare344bea2005-09-01 20:46:49 +00002344 buf->b_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002345 }
2346}
2347
2348#if defined(FEAT_WINDOWS) || defined(PROTO)
2349 void
2350python_window_free(win_T *win)
2351{
Bram Moolenaare344bea2005-09-01 20:46:49 +00002352 if (win->w_python_ref != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002353 {
Bram Moolenaare344bea2005-09-01 20:46:49 +00002354 WindowObject *wp = win->w_python_ref;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002355 wp->win = INVALID_WINDOW_VALUE;
Bram Moolenaare344bea2005-09-01 20:46:49 +00002356 win->w_python_ref = NULL;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002357 }
2358}
2359#endif
2360
2361static BufListObject TheBufferList =
2362{
2363 PyObject_HEAD_INIT(&BufListType)
2364};
2365
2366static WinListObject TheWindowList =
2367{
2368 PyObject_HEAD_INIT(&WinListType)
2369};
2370
2371static CurrentObject TheCurrent =
2372{
2373 PyObject_HEAD_INIT(&CurrentType)
2374};
2375
2376 static int
2377PythonMod_Init(void)
2378{
2379 PyObject *mod;
2380 PyObject *dict;
Bram Moolenaar9774ecc2008-11-20 10:04:53 +00002381 /* The special value is removed from sys.path in Python_Init(). */
2382 static char *(argv[2]) = {"/must>not&exist/foo", NULL};
Bram Moolenaar071d4272004-06-13 20:20:40 +00002383
2384 /* Fixups... */
2385 BufferType.ob_type = &PyType_Type;
2386 RangeType.ob_type = &PyType_Type;
2387 WindowType.ob_type = &PyType_Type;
2388 BufListType.ob_type = &PyType_Type;
2389 WinListType.ob_type = &PyType_Type;
2390 CurrentType.ob_type = &PyType_Type;
2391
2392 /* Set sys.argv[] to avoid a crash in warn(). */
2393 PySys_SetArgv(1, argv);
2394
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002395 mod = Py_InitModule4("vim", VimMethods, (char *)NULL, (PyObject *)NULL, PYTHON_API_VERSION);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002396 dict = PyModule_GetDict(mod);
2397
2398 VimError = Py_BuildValue("s", "vim.error");
2399
2400 PyDict_SetItemString(dict, "error", VimError);
Bram Moolenaar7df2d662005-01-25 22:18:08 +00002401 PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList);
2402 PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent);
2403 PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002404
2405 if (PyErr_Occurred())
2406 return -1;
2407
2408 return 0;
2409}
2410
2411/*************************************************************************
2412 * 4. Utility functions for handling the interface between Vim and Python.
2413 */
2414
2415/* Get a line from the specified buffer. The line number is
2416 * in Vim format (1-based). The line is returned as a Python
2417 * string object.
2418 */
2419 static PyObject *
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002420GetBufferLine(buf_T *buf, PyInt n)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002421{
2422 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2423}
2424
2425/* Get a list of lines from the specified buffer. The line numbers
2426 * are in Vim format (1-based). The range is from lo up to, but not
2427 * including, hi. The list is returned as a Python list of string objects.
2428 */
2429 static PyObject *
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002430GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002431{
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002432 PyInt i;
2433 PyInt n = hi - lo;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002434 PyObject *list = PyList_New(n);
2435
2436 if (list == NULL)
2437 return NULL;
2438
2439 for (i = 0; i < n; ++i)
2440 {
2441 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2442
2443 /* Error check - was the Python string creation OK? */
2444 if (str == NULL)
2445 {
2446 Py_DECREF(list);
2447 return NULL;
2448 }
2449
2450 /* Set the list item */
2451 if (PyList_SetItem(list, i, str))
2452 {
2453 Py_DECREF(str);
2454 Py_DECREF(list);
2455 return NULL;
2456 }
2457 }
2458
2459 /* The ownership of the Python list is passed to the caller (ie,
2460 * the caller should Py_DECREF() the object when it is finished
2461 * with it).
2462 */
2463
2464 return list;
2465}
2466
2467/*
2468 * Check if deleting lines made the cursor position invalid.
2469 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2470 * deleted).
2471 */
2472 static void
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002473py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002474{
2475 if (curwin->w_cursor.lnum >= lo)
2476 {
2477 /* Adjust the cursor position if it's in/after the changed
2478 * lines. */
2479 if (curwin->w_cursor.lnum >= hi)
2480 {
2481 curwin->w_cursor.lnum += extra;
2482 check_cursor_col();
2483 }
2484 else if (extra < 0)
2485 {
2486 curwin->w_cursor.lnum = lo;
2487 check_cursor();
2488 }
Bram Moolenaar454ec052007-03-08 09:20:28 +00002489 else
2490 check_cursor_col();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002491 changed_cline_bef_curs();
2492 }
2493 invalidate_botline();
2494}
2495
2496/* Replace a line in the specified buffer. The line number is
2497 * in Vim format (1-based). The replacement line is given as
2498 * a Python string object. The object is checked for validity
2499 * and correct format. Errors are returned as a value of FAIL.
2500 * The return value is OK on success.
2501 * If OK is returned and len_change is not NULL, *len_change
2502 * is set to the change in the buffer length.
2503 */
2504 static int
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002505SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002506{
2507 /* First of all, we check the thpe of the supplied Python object.
2508 * There are three cases:
2509 * 1. NULL, or None - this is a deletion.
2510 * 2. A string - this is a replacement.
2511 * 3. Anything else - this is an error.
2512 */
2513 if (line == Py_None || line == NULL)
2514 {
2515 buf_T *savebuf = curbuf;
2516
2517 PyErr_Clear();
2518 curbuf = buf;
2519
2520 if (u_savedel((linenr_T)n, 1L) == FAIL)
2521 PyErr_SetVim(_("cannot save undo information"));
2522 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2523 PyErr_SetVim(_("cannot delete line"));
2524 else
2525 {
Bram Moolenaar071d4272004-06-13 20:20:40 +00002526 if (buf == curwin->w_buffer)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002527 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaarcdcaa582009-07-09 18:06:49 +00002528 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002529 }
2530
2531 curbuf = savebuf;
2532
2533 if (PyErr_Occurred() || VimErrorCheck())
2534 return FAIL;
2535
2536 if (len_change)
2537 *len_change = -1;
2538
2539 return OK;
2540 }
2541 else if (PyString_Check(line))
2542 {
2543 char *save = StringToLine(line);
2544 buf_T *savebuf = curbuf;
2545
2546 if (save == NULL)
2547 return FAIL;
2548
2549 /* We do not need to free "save" if ml_replace() consumes it. */
2550 PyErr_Clear();
2551 curbuf = buf;
2552
2553 if (u_savesub((linenr_T)n) == FAIL)
2554 {
2555 PyErr_SetVim(_("cannot save undo information"));
2556 vim_free(save);
2557 }
2558 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2559 {
2560 PyErr_SetVim(_("cannot replace line"));
2561 vim_free(save);
2562 }
2563 else
2564 changed_bytes((linenr_T)n, 0);
2565
2566 curbuf = savebuf;
2567
Bram Moolenaar454ec052007-03-08 09:20:28 +00002568 /* Check that the cursor is not beyond the end of the line now. */
2569 if (buf == curwin->w_buffer)
2570 check_cursor_col();
2571
Bram Moolenaar071d4272004-06-13 20:20:40 +00002572 if (PyErr_Occurred() || VimErrorCheck())
2573 return FAIL;
2574
2575 if (len_change)
2576 *len_change = 0;
2577
2578 return OK;
2579 }
2580 else
2581 {
2582 PyErr_BadArgument();
2583 return FAIL;
2584 }
2585}
2586
2587/* Replace a range of lines in the specified buffer. The line numbers are in
2588 * Vim format (1-based). The range is from lo up to, but not including, hi.
2589 * The replacement lines are given as a Python list of string objects. The
2590 * list is checked for validity and correct format. Errors are returned as a
2591 * value of FAIL. The return value is OK on success.
2592 * If OK is returned and len_change is not NULL, *len_change
2593 * is set to the change in the buffer length.
2594 */
2595 static int
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002596SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002597{
2598 /* First of all, we check the thpe of the supplied Python object.
2599 * There are three cases:
2600 * 1. NULL, or None - this is a deletion.
2601 * 2. A list - this is a replacement.
2602 * 3. Anything else - this is an error.
2603 */
2604 if (list == Py_None || list == NULL)
2605 {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002606 PyInt i;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002607 PyInt n = (int)(hi - lo);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002608 buf_T *savebuf = curbuf;
2609
2610 PyErr_Clear();
2611 curbuf = buf;
2612
2613 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2614 PyErr_SetVim(_("cannot save undo information"));
2615 else
2616 {
2617 for (i = 0; i < n; ++i)
2618 {
2619 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2620 {
2621 PyErr_SetVim(_("cannot delete line"));
2622 break;
2623 }
2624 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002625 if (buf == curwin->w_buffer)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002626 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
Bram Moolenaarcdcaa582009-07-09 18:06:49 +00002627 deleted_lines_mark((linenr_T)lo, (long)i);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002628 }
2629
2630 curbuf = savebuf;
2631
2632 if (PyErr_Occurred() || VimErrorCheck())
2633 return FAIL;
2634
2635 if (len_change)
2636 *len_change = -n;
2637
2638 return OK;
2639 }
2640 else if (PyList_Check(list))
2641 {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002642 PyInt i;
2643 PyInt new_len = PyList_Size(list);
2644 PyInt old_len = hi - lo;
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002645 PyInt extra = 0; /* lines added to text, can be negative */
Bram Moolenaar071d4272004-06-13 20:20:40 +00002646 char **array;
2647 buf_T *savebuf;
2648
2649 if (new_len == 0) /* avoid allocating zero bytes */
2650 array = NULL;
2651 else
2652 {
2653 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2654 if (array == NULL)
2655 {
2656 PyErr_NoMemory();
2657 return FAIL;
2658 }
2659 }
2660
2661 for (i = 0; i < new_len; ++i)
2662 {
2663 PyObject *line = PyList_GetItem(list, i);
2664
2665 array[i] = StringToLine(line);
2666 if (array[i] == NULL)
2667 {
2668 while (i)
2669 vim_free(array[--i]);
2670 vim_free(array);
2671 return FAIL;
2672 }
2673 }
2674
2675 savebuf = curbuf;
2676
2677 PyErr_Clear();
2678 curbuf = buf;
2679
2680 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2681 PyErr_SetVim(_("cannot save undo information"));
2682
2683 /* If the size of the range is reducing (ie, new_len < old_len) we
2684 * need to delete some old_len. We do this at the start, by
2685 * repeatedly deleting line "lo".
2686 */
2687 if (!PyErr_Occurred())
2688 {
2689 for (i = 0; i < old_len - new_len; ++i)
2690 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2691 {
2692 PyErr_SetVim(_("cannot delete line"));
2693 break;
2694 }
2695 extra -= i;
2696 }
2697
2698 /* For as long as possible, replace the existing old_len with the
2699 * new old_len. This is a more efficient operation, as it requires
2700 * less memory allocation and freeing.
2701 */
2702 if (!PyErr_Occurred())
2703 {
2704 for (i = 0; i < old_len && i < new_len; ++i)
2705 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2706 == FAIL)
2707 {
2708 PyErr_SetVim(_("cannot replace line"));
2709 break;
2710 }
2711 }
2712 else
2713 i = 0;
2714
2715 /* Now we may need to insert the remaining new old_len. If we do, we
2716 * must free the strings as we finish with them (we can't pass the
2717 * responsibility to vim in this case).
2718 */
2719 if (!PyErr_Occurred())
2720 {
2721 while (i < new_len)
2722 {
2723 if (ml_append((linenr_T)(lo + i - 1),
2724 (char_u *)array[i], 0, FALSE) == FAIL)
2725 {
2726 PyErr_SetVim(_("cannot insert line"));
2727 break;
2728 }
2729 vim_free(array[i]);
2730 ++i;
2731 ++extra;
2732 }
2733 }
2734
2735 /* Free any left-over old_len, as a result of an error */
2736 while (i < new_len)
2737 {
2738 vim_free(array[i]);
2739 ++i;
2740 }
2741
2742 /* Free the array of old_len. All of its contents have now
2743 * been dealt with (either freed, or the responsibility passed
2744 * to vim.
2745 */
2746 vim_free(array);
2747
2748 /* Adjust marks. Invalidate any which lie in the
2749 * changed range, and move any in the remainder of the buffer.
2750 */
2751 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2752 (long)MAXLNUM, (long)extra);
2753 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2754
2755 if (buf == curwin->w_buffer)
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002756 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002757
2758 curbuf = savebuf;
2759
2760 if (PyErr_Occurred() || VimErrorCheck())
2761 return FAIL;
2762
2763 if (len_change)
2764 *len_change = new_len - old_len;
2765
2766 return OK;
2767 }
2768 else
2769 {
2770 PyErr_BadArgument();
2771 return FAIL;
2772 }
2773}
2774
2775/* Insert a number of lines into the specified buffer after the specifed line.
2776 * The line number is in Vim format (1-based). The lines to be inserted are
2777 * given as a Python list of string objects or as a single string. The lines
2778 * to be added are checked for validity and correct format. Errors are
2779 * returned as a value of FAIL. The return value is OK on success.
2780 * If OK is returned and len_change is not NULL, *len_change
2781 * is set to the change in the buffer length.
2782 */
2783 static int
Bram Moolenaare7cb9cf2008-06-20 14:32:41 +00002784InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002785{
2786 /* First of all, we check the type of the supplied Python object.
2787 * It must be a string or a list, or the call is in error.
2788 */
2789 if (PyString_Check(lines))
2790 {
2791 char *str = StringToLine(lines);
2792 buf_T *savebuf;
2793
2794 if (str == NULL)
2795 return FAIL;
2796
2797 savebuf = curbuf;
2798
2799 PyErr_Clear();
2800 curbuf = buf;
2801
2802 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2803 PyErr_SetVim(_("cannot save undo information"));
2804 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2805 PyErr_SetVim(_("cannot insert line"));
2806 else
2807 appended_lines_mark((linenr_T)n, 1L);
2808
2809 vim_free(str);
2810 curbuf = savebuf;
2811 update_screen(VALID);
2812
2813 if (PyErr_Occurred() || VimErrorCheck())
2814 return FAIL;
2815
2816 if (len_change)
2817 *len_change = 1;
2818
2819 return OK;
2820 }
2821 else if (PyList_Check(lines))
2822 {
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002823 PyInt i;
2824 PyInt size = PyList_Size(lines);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002825 char **array;
2826 buf_T *savebuf;
2827
2828 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2829 if (array == NULL)
2830 {
2831 PyErr_NoMemory();
2832 return FAIL;
2833 }
2834
2835 for (i = 0; i < size; ++i)
2836 {
2837 PyObject *line = PyList_GetItem(lines, i);
2838 array[i] = StringToLine(line);
2839
2840 if (array[i] == NULL)
2841 {
2842 while (i)
2843 vim_free(array[--i]);
2844 vim_free(array);
2845 return FAIL;
2846 }
2847 }
2848
2849 savebuf = curbuf;
2850
2851 PyErr_Clear();
2852 curbuf = buf;
2853
2854 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2855 PyErr_SetVim(_("cannot save undo information"));
2856 else
2857 {
2858 for (i = 0; i < size; ++i)
2859 {
2860 if (ml_append((linenr_T)(n + i),
2861 (char_u *)array[i], 0, FALSE) == FAIL)
2862 {
2863 PyErr_SetVim(_("cannot insert line"));
2864
2865 /* Free the rest of the lines */
2866 while (i < size)
2867 vim_free(array[i++]);
2868
2869 break;
2870 }
2871 vim_free(array[i]);
2872 }
2873 if (i > 0)
2874 appended_lines_mark((linenr_T)n, (long)i);
2875 }
2876
2877 /* Free the array of lines. All of its contents have now
2878 * been freed.
2879 */
2880 vim_free(array);
2881
2882 curbuf = savebuf;
2883 update_screen(VALID);
2884
2885 if (PyErr_Occurred() || VimErrorCheck())
2886 return FAIL;
2887
2888 if (len_change)
2889 *len_change = size;
2890
2891 return OK;
2892 }
2893 else
2894 {
2895 PyErr_BadArgument();
2896 return FAIL;
2897 }
2898}
2899
2900/* Convert a Vim line into a Python string.
2901 * All internal newlines are replaced by null characters.
2902 *
2903 * On errors, the Python exception data is set, and NULL is returned.
2904 */
2905 static PyObject *
2906LineToString(const char *str)
2907{
2908 PyObject *result;
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002909 PyInt len = strlen(str);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002910 char *p;
2911
2912 /* Allocate an Python string object, with uninitialised contents. We
2913 * must do it this way, so that we can modify the string in place
2914 * later. See the Python source, Objects/stringobject.c for details.
2915 */
2916 result = PyString_FromStringAndSize(NULL, len);
2917 if (result == NULL)
2918 return NULL;
2919
2920 p = PyString_AsString(result);
2921
2922 while (*str)
2923 {
2924 if (*str == '\n')
2925 *p = '\0';
2926 else
2927 *p = *str;
2928
2929 ++p;
2930 ++str;
2931 }
2932
2933 return result;
2934}
2935
2936/* Convert a Python string into a Vim line.
2937 *
2938 * The result is in allocated memory. All internal nulls are replaced by
2939 * newline characters. It is an error for the string to contain newline
2940 * characters.
2941 *
2942 * On errors, the Python exception data is set, and NULL is returned.
2943 */
2944 static char *
2945StringToLine(PyObject *obj)
2946{
2947 const char *str;
2948 char *save;
Bram Moolenaar2c45e942008-06-04 11:35:26 +00002949 PyInt len;
2950 PyInt i;
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002951 char *p;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002952
2953 if (obj == NULL || !PyString_Check(obj))
2954 {
2955 PyErr_BadArgument();
2956 return NULL;
2957 }
2958
2959 str = PyString_AsString(obj);
2960 len = PyString_Size(obj);
2961
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002962 /*
2963 * Error checking: String must not contain newlines, as we
Bram Moolenaar071d4272004-06-13 20:20:40 +00002964 * are replacing a single line, and we must replace it with
2965 * a single line.
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002966 * A trailing newline is removed, so that append(f.readlines()) works.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002967 */
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002968 p = memchr(str, '\n', len);
2969 if (p != NULL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002970 {
Bram Moolenaar5eb86f92004-07-26 12:53:41 +00002971 if (p == str + len - 1)
2972 --len;
2973 else
2974 {
2975 PyErr_SetVim(_("string cannot contain newlines"));
2976 return NULL;
2977 }
Bram Moolenaar071d4272004-06-13 20:20:40 +00002978 }
2979
2980 /* Create a copy of the string, with internal nulls replaced by
2981 * newline characters, as is the vim convention.
2982 */
2983 save = (char *)alloc((unsigned)(len+1));
2984 if (save == NULL)
2985 {
2986 PyErr_NoMemory();
2987 return NULL;
2988 }
2989
2990 for (i = 0; i < len; ++i)
2991 {
2992 if (str[i] == '\0')
2993 save[i] = '\n';
2994 else
2995 save[i] = str[i];
2996 }
2997
2998 save[i] = '\0';
2999
3000 return save;
3001}
3002
3003/* Check to see whether a Vim error has been reported, or a keyboard
3004 * interrupt has been detected.
3005 */
3006 static int
3007VimErrorCheck(void)
3008{
3009 if (got_int)
3010 {
3011 PyErr_SetNone(PyExc_KeyboardInterrupt);
3012 return 1;
3013 }
3014 else if (did_emsg && !PyErr_Occurred())
3015 {
3016 PyErr_SetNone(VimError);
3017 return 1;
3018 }
3019
3020 return 0;
3021}
3022
3023
3024/* Don't generate a prototype for the next function, it generates an error on
3025 * newer Python versions. */
3026#if PYTHON_API_VERSION < 1007 /* Python 1.4 */ && !defined(PROTO)
3027
3028 char *
3029Py_GetProgramName(void)
3030{
3031 return "vim";
3032}
3033#endif /* Python 1.4 */