blob: 238f968b3f2e99821cb29e019b452a9a6fbb2447 [file] [log] [blame]
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001/* 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/*
21 * Roland Puntaier 2009/sept/16:
22 * Adaptations to support both python3.x and python2.x
23 */
24
25// uncomment this if used with the debug version of python
26// #define Py_DEBUG
27
28#include "vim.h"
29
30#include <limits.h>
31
32/* Python.h defines _POSIX_THREADS itself (if needed) */
33#ifdef _POSIX_THREADS
34# undef _POSIX_THREADS
35#endif
36
37#if defined(_WIN32) && defined (HAVE_FCNTL_H)
38# undef HAVE_FCNTL_H
39#endif
40
41#ifdef _DEBUG
42# undef _DEBUG
43#endif
44
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020045#define PY_SSIZE_T_CLEAN
46
47#ifdef F_BLANK
48# undef F_BLANK
49#endif
50
Bram Moolenaar6df6f472010-07-18 18:04:50 +020051#ifdef HAVE_STDARG_H
52# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
53#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020054#ifdef _POSIX_C_SOURCE /* defined in feature.h */
55# undef _POSIX_C_SOURCE
56#endif
Bram Moolenaar6df6f472010-07-18 18:04:50 +020057#ifdef _XOPEN_SOURCE
58# undef _XOPEN_SOURCE /* pyconfig.h defines it as well. */
59#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020060
61#include <Python.h>
62#if defined(MACOS) && !defined(MACOS_X_UNIX)
63# include "macglue.h"
64# include <CodeFragments.h>
65#endif
66#undef main /* Defined in python.h - aargh */
67#undef HAVE_FCNTL_H /* Clash with os_win32.h */
68
69static void init_structs(void);
70
71#if defined(DYNAMIC_PYTHON3)
72
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020073#ifndef WIN3264
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020074#include <dlfcn.h>
75#define FARPROC void*
76#define HINSTANCE void*
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020077#define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020078#define close_dll dlclose
79#define symbol_from_dll dlsym
80#else
81#define load_dll LoadLibrary
82#define close_dll FreeLibrary
83#define symbol_from_dll GetProcAddress
84#endif
85/*
86 * Wrapper defines
87 */
88#undef PyArg_Parse
89# define PyArg_Parse py3_PyArg_Parse
90#undef PyArg_ParseTuple
91# define PyArg_ParseTuple py3_PyArg_ParseTuple
92# define PyDict_SetItemString py3_PyDict_SetItemString
93# define PyErr_BadArgument py3_PyErr_BadArgument
94# define PyErr_Clear py3_PyErr_Clear
95# define PyErr_NoMemory py3_PyErr_NoMemory
96# define PyErr_Occurred py3_PyErr_Occurred
97# define PyErr_SetNone py3_PyErr_SetNone
98# define PyErr_SetString py3_PyErr_SetString
99# define PyEval_InitThreads py3_PyEval_InitThreads
100# define PyEval_RestoreThread py3_PyEval_RestoreThread
101# define PyEval_SaveThread py3_PyEval_SaveThread
102# define PyGILState_Ensure py3_PyGILState_Ensure
103# define PyGILState_Release py3_PyGILState_Release
104# define PyLong_AsLong py3_PyLong_AsLong
105# define PyLong_FromLong py3_PyLong_FromLong
106# define PyList_GetItem py3_PyList_GetItem
107# define PyList_Append py3_PyList_Append
108# define PyList_New py3_PyList_New
109# define PyList_SetItem py3_PyList_SetItem
110# define PyList_Size py3_PyList_Size
111# define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
112# define PyImport_ImportModule py3_PyImport_ImportModule
113# define PyObject_Init py3__PyObject_Init
114# define PyDict_New py3_PyDict_New
115# define PyDict_GetItemString py3_PyDict_GetItemString
116# define PyModule_GetDict py3_PyModule_GetDict
117#undef PyRun_SimpleString
118# define PyRun_SimpleString py3_PyRun_SimpleString
119# define PySys_SetObject py3_PySys_SetObject
120# define PySys_SetArgv py3_PySys_SetArgv
121# define PyType_Type (*py3_PyType_Type)
122# define PyType_Ready py3_PyType_Ready
123#undef Py_BuildValue
124# define Py_BuildValue py3_Py_BuildValue
125# define Py_Initialize py3_Py_Initialize
126# define Py_Finalize py3_Py_Finalize
127# define Py_IsInitialized py3_Py_IsInitialized
128# define _Py_NoneStruct (*py3__Py_NoneStruct)
129# define PyModule_AddObject py3_PyModule_AddObject
130# define PyImport_AppendInittab py3_PyImport_AppendInittab
131# define _PyUnicode_AsString py3__PyUnicode_AsString
132# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
133# define PySlice_Type (*py3_PySlice_Type)
134#ifdef Py_DEBUG
135 # define _Py_NegativeRefcount py3__Py_NegativeRefcount
136 # define _Py_RefTotal (*py3__Py_RefTotal)
137 # define _Py_Dealloc py3__Py_Dealloc
138 # define _PyObject_DebugMalloc py3__PyObject_DebugMalloc
139 # define _PyObject_DebugFree py3__PyObject_DebugFree
140#else
141 # define PyObject_Malloc py3_PyObject_Malloc
142 # define PyObject_Free py3_PyObject_Free
143#endif
144# define PyType_GenericAlloc py3_PyType_GenericAlloc
145# define PyType_GenericNew py3_PyType_GenericNew
146# define PyModule_Create2 py3_PyModule_Create2
147#undef PyUnicode_FromString
148# define PyUnicode_FromString py3_PyUnicode_FromString
149#undef PyUnicode_FromStringAndSize
150# define PyUnicode_FromStringAndSize py3_PyUnicode_FromStringAndSize
151
152#ifdef Py_DEBUG
153#undef PyObject_NEW
154#define PyObject_NEW(type, typeobj) \
155( (type *) PyObject_Init( \
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200156 (PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200157#endif
158/*
159 * Pointers for dynamic link
160 */
161static int (*py3_PySys_SetArgv)(int, wchar_t **);
162static void (*py3_Py_Initialize)(void);
163static PyObject* (*py3_PyList_New)(Py_ssize_t size);
164static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
165static void (*py3_PyGILState_Release)(PyGILState_STATE);
166static int (*py3_PySys_SetObject)(char *, PyObject *);
167static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
168static Py_ssize_t (*py3_PyList_Size)(PyObject *);
169static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200170 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200171static PyObject* (*py3_PyErr_NoMemory)(void);
172static void (*py3_Py_Finalize)(void);
173static void (*py3_PyErr_SetString)(PyObject *, const char *);
174static int (*py3_PyRun_SimpleString)(char *);
175static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
176static PyObject* (*py3_PyImport_ImportModule)(const char *);
177static int (*py3_PyErr_BadArgument)(void);
178static PyTypeObject* py3_PyType_Type;
179static PyObject* (*py3_PyErr_Occurred)(void);
180static PyObject* (*py3_PyModule_GetDict)(PyObject *);
181static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
182static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
183static PyObject* (*py3_PyLong_FromLong)(long);
184static PyObject* (*py3_PyDict_New)(void);
185static PyObject* (*py3_Py_BuildValue)(char *, ...);
186static int (*py3_PyType_Ready)(PyTypeObject *type);
187static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
188static PyObject* (*py3_PyUnicode_FromString)(const char *u);
189static PyObject* (*py3_PyUnicode_FromStringAndSize)(const char *u, Py_ssize_t size);
190static long (*py3_PyLong_AsLong)(PyObject *);
191static void (*py3_PyErr_SetNone)(PyObject *);
192static void (*py3_PyEval_InitThreads)(void);
193static void(*py3_PyEval_RestoreThread)(PyThreadState *);
194static PyThreadState*(*py3_PyEval_SaveThread)(void);
195static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
196static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
197static int (*py3_Py_IsInitialized)(void);
198static void (*py3_PyErr_Clear)(void);
199static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
200static PyObject* py3__Py_NoneStruct;
201static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
202static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
203static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
204static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
205static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
206static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
207static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
208static PyTypeObject* py3_PySlice_Type;
209#ifdef Py_DEBUG
210 static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
211 static Py_ssize_t* py3__Py_RefTotal;
212 static void (*py3__Py_Dealloc)(PyObject *obj);
213 static void (*py3__PyObject_DebugFree)(void*);
214 static void* (*py3__PyObject_DebugMalloc)(size_t);
215#else
216 static void (*py3_PyObject_Free)(void*);
217 static void* (*py3_PyObject_Malloc)(size_t);
218#endif
219
220static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
221
222/* Imported exception objects */
223static PyObject *p3imp_PyExc_AttributeError;
224static PyObject *p3imp_PyExc_IndexError;
225static PyObject *p3imp_PyExc_KeyboardInterrupt;
226static PyObject *p3imp_PyExc_TypeError;
227static PyObject *p3imp_PyExc_ValueError;
228
229# define PyExc_AttributeError p3imp_PyExc_AttributeError
230# define PyExc_IndexError p3imp_PyExc_IndexError
231# define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
232# define PyExc_TypeError p3imp_PyExc_TypeError
233# define PyExc_ValueError p3imp_PyExc_ValueError
234
235/*
236 * Table of name to function pointer of python.
237 */
238# define PYTHON_PROC FARPROC
239static struct
240{
241 char *name;
242 PYTHON_PROC *ptr;
243} py3_funcname_table[] =
244{
245 {"PySys_SetArgv", (PYTHON_PROC*)&py3_PySys_SetArgv},
246 {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
247 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
248 {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
249 {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
250 {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
251 {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
252 {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
253 {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
254 {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
255 {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
256 {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
257 {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
258 {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
259 {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
260 {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
261 {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
262 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
263 {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
264 {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
265 {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
266 {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
267 {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
268 {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
269 {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
270 {"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
271 {"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
272 {"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
273 {"PyErr_SetNone", (PYTHON_PROC*)&py3_PyErr_SetNone},
274 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads},
275 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread},
276 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
277 {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
278 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
279 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
280 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
281 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
282 {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
283 {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
284 {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
285 {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
286 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
287 {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
288 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
289 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
290 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
291#ifdef Py_DEBUG
292 {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
293 {"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
294 {"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
295 {"_PyObject_DebugFree", (PYTHON_PROC*)&py3__PyObject_DebugFree},
296 {"_PyObject_DebugMalloc", (PYTHON_PROC*)&py3__PyObject_DebugMalloc},
297#else
298 {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
299 {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
300#endif
301 {"", NULL},
302};
303
304/*
305 * Free python.dll
306 */
307static void end_dynamic_python3(void)
308{
309 if (hinstPy3)
310 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200311 close_dll(hinstPy3);
312 hinstPy3 = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200313 }
314}
315
316/*
317 * Load library and get all pointers.
318 * Parameter 'libname' provides name of DLL.
319 * Return OK or FAIL.
320 */
321static int py3_runtime_link_init(char *libname, int verbose)
322{
323 int i;
Bram Moolenaar69154f22010-07-18 21:42:34 +0200324 void *ucs_from_string, *ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200325
326 if (hinstPy3)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200327 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200328 hinstPy3 = load_dll(libname);
329
330 if (!hinstPy3)
331 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200332 if (verbose)
333 EMSG2(_(e_loadlib), libname);
334 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200335 }
336
337 for (i = 0; py3_funcname_table[i].ptr; ++i)
338 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200339 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
340 py3_funcname_table[i].name)) == NULL)
341 {
342 close_dll(hinstPy3);
343 hinstPy3 = 0;
344 if (verbose)
345 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
346 return FAIL;
347 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200348 }
349
Bram Moolenaar69154f22010-07-18 21:42:34 +0200350 /* Load unicode functions separately as only the ucs2 or the ucs4 functions
351 * will be present in the library. */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200352 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
353 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200354 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200355 if (!ucs_from_string || !ucs_from_string_and_size)
356 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200357 ucs_from_string = symbol_from_dll(hinstPy3,
358 "PyUnicodeUCS4_FromString");
359 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
360 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200361 }
362 if (ucs_from_string && ucs_from_string_and_size)
363 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200364 py3_PyUnicode_FromString = ucs_from_string;
365 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200366 }
367 else
368 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200369 close_dll(hinstPy3);
370 hinstPy3 = 0;
371 if (verbose)
372 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
373 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200374 }
375
376 return OK;
377}
378
379/*
380 * If python is enabled (there is installed python on Windows system) return
381 * TRUE, else FALSE.
382 */
383int python3_enabled(int verbose)
384{
385 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
386}
387
388/* Load the standard Python exceptions - don't import the symbols from the
389 * DLL, as this can cause errors (importing data symbols is not reliable).
390 */
391static void get_py3_exceptions __ARGS((void));
392
393static void get_py3_exceptions()
394{
395 PyObject *exmod = PyImport_ImportModule("builtins");
396 PyObject *exdict = PyModule_GetDict(exmod);
397 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
398 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
399 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
400 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
401 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
402 Py_XINCREF(p3imp_PyExc_AttributeError);
403 Py_XINCREF(p3imp_PyExc_IndexError);
404 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
405 Py_XINCREF(p3imp_PyExc_TypeError);
406 Py_XINCREF(p3imp_PyExc_ValueError);
407 Py_XDECREF(exmod);
408}
409#endif /* DYNAMIC_PYTHON3 */
410
411static void call_PyObject_Free(void *p)
412{
413#ifdef Py_DEBUG
414 _PyObject_DebugFree(p);
415#else
416 PyObject_Free(p);
417#endif
418}
419static PyObject* call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
420{
421 return PyType_GenericNew(type,args,kwds);
422}
423static PyObject* call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
424{
425 return PyType_GenericAlloc(type,nitems);
426}
427
428/******************************************************
429 * Internal function prototypes.
430 */
431
432static void DoPy3Command(exarg_T *, const char *);
433static Py_ssize_t RangeStart;
434static Py_ssize_t RangeEnd;
435
436static void PythonIO_Flush(void);
437static int PythonIO_Init(void);
438static void PythonIO_Fini(void);
Bram Moolenaar69154f22010-07-18 21:42:34 +0200439PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200440
441/* Utility functions for the vim/python interface
442 * ----------------------------------------------
443 */
444static PyObject *GetBufferLine(buf_T *, Py_ssize_t);
445
446static int SetBufferLine(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
447static int InsertBufferLines(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
448static PyObject *GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi);
449
450static PyObject *LineToString(const char *);
451static char *StringToLine(PyObject *);
452
453static int VimErrorCheck(void);
454
455#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
456
457/******************************************************
458 * 1. Python interpreter main program.
459 */
460
461static int py3initialised = 0;
462
463
464static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
465
466/*
467 * obtain a lock on the Vim data structures
468 */
469static void Python_Lock_Vim(void)
470{
471}
472
473/*
474 * release a lock on the Vim data structures
475 */
476static void Python_Release_Vim(void)
477{
478}
479
480void python3_end()
481{
482 static int recurse = 0;
483
484 /* If a crash occurs while doing this, don't try again. */
485 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200486 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200487
488 ++recurse;
489
490#ifdef DYNAMIC_PYTHON3
491 if (hinstPy3)
492#endif
493 if (Py_IsInitialized())
494 {
495 // acquire lock before finalizing
496 pygilstate = PyGILState_Ensure();
497
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200498 PythonIO_Fini();
499 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200500 }
501
502#ifdef DYNAMIC_PYTHON3
503 end_dynamic_python3();
504#endif
505
506 --recurse;
507}
508
509static int Python3_Init(void)
510{
511 if (!py3initialised)
512 {
513#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200514 if (!python3_enabled(TRUE))
515 {
516 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
517 goto fail;
518 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200519#endif
520
521 init_structs();
522
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200523 /* initialise threads */
524 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200525
526#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200527 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200528#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200529 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200530#endif
531
532#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200533 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200534#endif
535
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200536 if (PythonIO_Init())
537 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200538
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200539 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200540
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200541 /* Remove the element from sys.path that was added because of our
542 * argv[0] value in Py3Init_vim(). Previously we used an empty
543 * string, but dependinding on the OS we then get an empty entry or
544 * the current directory in sys.path. */
545 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200546
547 // lock is created and acquired in PyEval_InitThreads() and thread
548 // state is created in Py_Initialize()
549 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
550 // (python must have threads enabled!)
551 // so the following does both: unlock GIL and save thread state in TLS
552 // without deleting thread state
553 PyGILState_Release(pygilstate);
554
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200555 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200556 }
557
558 return 0;
559
560fail:
561 /* We call PythonIO_Flush() here to print any Python errors.
562 * This is OK, as it is possible to call this function even
563 * if PythonIO_Init() has not completed successfully (it will
564 * not do anything in this case).
565 */
566 PythonIO_Flush();
567 return -1;
568}
569
570/*
571 * External interface
572 */
573static void DoPy3Command(exarg_T *eap, const char *cmd)
574{
575#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200576 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200577#endif
578#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200579 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200580#endif
581
582#if defined(MACOS) && !defined(MACOS_X_UNIX)
583 GetPort(&oldPort);
584 /* Check if the Python library is available */
585 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200586 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200587#endif
588 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200589 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200590
591 RangeStart = eap->line1;
592 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200593 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200594
595#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
596 /* Python only works properly when the LC_NUMERIC locale is "C". */
597 saved_locale = setlocale(LC_NUMERIC, NULL);
598 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200599 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200600 else
601 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200602 /* Need to make a copy, value may change when setting new locale. */
603 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
604 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200605 }
606#endif
607
608 pygilstate = PyGILState_Ensure();
609
610 PyRun_SimpleString((char *)(cmd));
611
612 PyGILState_Release(pygilstate);
613
614#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
615 if (saved_locale != NULL)
616 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200617 (void)setlocale(LC_NUMERIC, saved_locale);
618 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200619 }
620#endif
621
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200622 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200623 PythonIO_Flush();
624#if defined(MACOS) && !defined(MACOS_X_UNIX)
625 SetPort(oldPort);
626#endif
627
628theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200629 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200630}
631
632/*
Bram Moolenaar368373e2010-07-19 20:46:22 +0200633 * ":py3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200634 */
Bram Moolenaar368373e2010-07-19 20:46:22 +0200635void ex_py3(exarg_T *eap)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200636{
637 char_u *script;
638
639 script = script_get(eap, eap->arg);
640 if (!eap->skip)
641 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200642 if (script == NULL)
643 DoPy3Command(eap, (char *)eap->arg);
644 else
645 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200646 }
647 vim_free(script);
648}
649
650#define BUFFER_SIZE 2048
651
652/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200653 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200654 */
655 void
656ex_py3file(exarg_T *eap)
657{
658 static char buffer[BUFFER_SIZE];
659 const char *file;
660 char *p;
661 int i;
662
663 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
664 * stdio file pointer, but Vim and the Python DLL are compiled with
665 * different options under Windows, meaning that stdio pointers aren't
666 * compatible between the two. Yuk.
667 *
668 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
669 *
670 * We need to escape any backslashes or single quotes in the file name, so that
671 * Python won't mangle the file name.
672 */
673
674 strcpy(buffer, "exec(compile(open('");
675 p = buffer + 19; /* size of "exec(compile(open('" */
676
677 for (i=0; i<2; ++i)
678 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200679 file = (char *)eap->arg;
680 while (*file && p < buffer + (BUFFER_SIZE - 3))
681 {
682 if (*file == '\\' || *file == '\'')
683 *p++ = '\\';
684 *p++ = *file++;
685 }
686 /* If we didn't finish the file name, we hit a buffer overflow */
687 if (*file != '\0')
688 return;
689 if (i==0)
690 {
691 strcpy(p,"').read(),'");
692 p += 11;
693 }
694 else
695 {
696 strcpy(p,"','exec'))");
697 p += 10;
698 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200699 }
700
701
702 /* Execute the file */
703 DoPy3Command(eap, buffer);
704}
705
706/******************************************************
707 * 2. Python output stream: writes output via [e]msg().
708 */
709
710/* Implementation functions
711 */
712
713static PyObject *OutputGetattro(PyObject *, PyObject *);
714static int OutputSetattro(PyObject *, PyObject *, PyObject *);
715
716static PyObject *OutputWrite(PyObject *, PyObject *);
717static PyObject *OutputWritelines(PyObject *, PyObject *);
718
719typedef void (*writefn)(char_u *);
720static void writer(writefn fn, char_u *str, Py_ssize_t n);
721
722/* Output object definition
723 */
724
725typedef struct
726{
727 PyObject_HEAD
728 long softspace;
729 long error;
730} OutputObject;
731
732static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200733 /* name, function, calling, documentation */
734 {"write", OutputWrite, 1, "" },
735 {"writelines", OutputWritelines, 1, "" },
736 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200737};
738
739static PyTypeObject OutputType;
740
741/*************/
742
743static PyObject * OutputGetattro(PyObject *self, PyObject *nameobj)
744{
745 char *name = "";
746 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200747 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200748
749 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200750 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200751
752 return PyObject_GenericGetAttr(self, nameobj);
753}
754
755static int OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
756{
757 char *name = "";
758 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200759 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200760
761 if (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200762 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
763 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200764 }
765
766 if (strcmp(name, "softspace") == 0)
767 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200768 if (!PyLong_Check(val)) {
769 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
770 return -1;
771 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200772
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200773 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
774 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200775 }
776
777 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
778 return -1;
779}
780
781/*************/
782
783static PyObject * OutputWrite(PyObject *self, PyObject *args)
784{
785 int len;
786 char *str;
787 int error = ((OutputObject *)(self))->error;
788
789 if (!PyArg_ParseTuple(args, "s#", &str, &len))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200790 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200791
792 Py_BEGIN_ALLOW_THREADS
793 Python_Lock_Vim();
794 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
795 Python_Release_Vim();
796 Py_END_ALLOW_THREADS
797
798 Py_INCREF(Py_None);
799 return Py_None;
800}
801
802static PyObject * OutputWritelines(PyObject *self, PyObject *args)
803{
804 Py_ssize_t n;
805 Py_ssize_t i;
806 PyObject *list;
807 int error = ((OutputObject *)(self))->error;
808
809 if (!PyArg_ParseTuple(args, "O", &list))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200810 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200811 Py_INCREF(list);
812
813 if (!PyList_Check(list)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200814 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
815 Py_DECREF(list);
816 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200817 }
818
819 n = PyList_Size(list);
820
821 for (i = 0; i < n; ++i)
822 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200823 PyObject *line = PyList_GetItem(list, i);
824 char *str;
825 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200826
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200827 if (!PyArg_Parse(line, "s#", &str, &len)) {
828 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
829 Py_DECREF(list);
830 return NULL;
831 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200832
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200833 Py_BEGIN_ALLOW_THREADS
834 Python_Lock_Vim();
835 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
836 Python_Release_Vim();
837 Py_END_ALLOW_THREADS
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200838 }
839
840 Py_DECREF(list);
841 Py_INCREF(Py_None);
842 return Py_None;
843}
844
845/* Output buffer management
846 */
847
848static char_u *buffer = NULL;
849static Py_ssize_t buffer_len = 0;
850static Py_ssize_t buffer_size = 0;
851
852static writefn old_fn = NULL;
853
854static void buffer_ensure(Py_ssize_t n)
855{
856 Py_ssize_t new_size;
857 char_u *new_buffer;
858
859 if (n < buffer_size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200860 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200861
862 new_size = buffer_size;
863 while (new_size < n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200864 new_size += 80;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200865
866 if (new_size != buffer_size)
867 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200868 new_buffer = alloc((unsigned)new_size);
869 if (new_buffer == NULL)
870 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200871
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200872 if (buffer)
873 {
874 memcpy(new_buffer, buffer, buffer_len);
875 vim_free(buffer);
876 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200877
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200878 buffer = new_buffer;
879 buffer_size = new_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200880 }
881}
882
883static void PythonIO_Flush(void)
884{
885 if (old_fn && buffer_len)
886 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200887 buffer[buffer_len] = 0;
888 old_fn(buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200889 }
890
891 buffer_len = 0;
892}
893
894static void writer(writefn fn, char_u *str, Py_ssize_t n)
895{
896 char_u *ptr;
897
898 if (fn != old_fn && old_fn != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200899 PythonIO_Flush();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200900
901 old_fn = fn;
902
903 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
904 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200905 Py_ssize_t len = ptr - str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200906
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200907 buffer_ensure(buffer_len + len + 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200908
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200909 memcpy(buffer + buffer_len, str, len);
910 buffer_len += len;
911 buffer[buffer_len] = 0;
912 fn(buffer);
913 str = ptr + 1;
914 n -= len + 1;
915 buffer_len = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200916 }
917
918 /* Put the remaining text into the buffer for later printing */
919 buffer_ensure(buffer_len + n + 1);
920 memcpy(buffer + buffer_len, str, n);
921 buffer_len += n;
922}
923
924/***************/
925
926static OutputObject Output =
927{
928 PyObject_HEAD_INIT(&OutputType)
929 0,
930 0
931};
932
933static OutputObject Error =
934{
935 PyObject_HEAD_INIT(&OutputType)
936 0,
937 1
938};
939
940static int PythonIO_Init(void)
941{
942 PyType_Ready(&OutputType);
943
944 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
945 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
946
947 if (PyErr_Occurred())
948 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200949 EMSG(_("E264: Python: Error initialising I/O objects"));
950 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200951 }
952
953 return 0;
954}
955static void PythonIO_Fini(void)
956{
957 PySys_SetObject("stdout", NULL);
958 PySys_SetObject("stderr", NULL);
959}
960
961/******************************************************
962 * 3. Implementation of the Vim module for Python
963 */
964
965/* Vim module - Implementation functions
966 * -------------------------------------
967 */
968
969static PyObject *VimError;
970
971static PyObject *VimCommand(PyObject *, PyObject *);
972static PyObject *VimEval(PyObject *, PyObject *);
973
974/* Window type - Implementation functions
975 * --------------------------------------
976 */
977
978typedef struct
979{
980 PyObject_HEAD
981 win_T *win;
982}
983WindowObject;
984
985#define INVALID_WINDOW_VALUE ((win_T *)(-1))
986
987#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
988
989static PyObject *WindowNew(win_T *);
990
991static void WindowDestructor(PyObject *);
992static PyObject *WindowGetattro(PyObject *, PyObject *);
993static int WindowSetattro(PyObject *, PyObject *, PyObject *);
994static PyObject *WindowRepr(PyObject *);
995
996/* Buffer type - Implementation functions
997 * --------------------------------------
998 */
999
1000typedef struct
1001{
1002 PyObject_HEAD
1003 buf_T *buf;
1004}
1005BufferObject;
1006
1007#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
1008
1009#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
1010
1011static PyObject *BufferNew (buf_T *);
1012
1013static void BufferDestructor(PyObject *);
1014
1015static PyObject *BufferGetattro(PyObject *, PyObject*);
1016static PyObject *BufferRepr(PyObject *);
1017
1018static Py_ssize_t BufferLength(PyObject *);
1019static PyObject *BufferItem(PyObject *, Py_ssize_t);
1020static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
1021static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
1022
1023static PyObject *BufferAppend(PyObject *, PyObject *);
1024static PyObject *BufferMark(PyObject *, PyObject *);
1025static PyObject *BufferRange(PyObject *, PyObject *);
1026
1027/* Line range type - Implementation functions
1028 * --------------------------------------
1029 */
1030
1031typedef struct
1032{
1033 PyObject_HEAD
1034 BufferObject *buf;
1035 Py_ssize_t start;
1036 Py_ssize_t end;
1037}
1038RangeObject;
1039
1040#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
1041
1042static PyObject *RangeNew(buf_T *, Py_ssize_t, Py_ssize_t);
1043
1044static void RangeDestructor(PyObject *);
1045static PyObject *RangeGetattro(PyObject *, PyObject *);
1046static PyObject *RangeRepr(PyObject *);
1047static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
1048
1049static Py_ssize_t RangeLength(PyObject *);
1050static PyObject *RangeItem(PyObject *, Py_ssize_t);
1051static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
1052
1053static PyObject *RangeAppend(PyObject *, PyObject *);
1054
1055/* Window list type - Implementation functions
1056 * -------------------------------------------
1057 */
1058
1059static Py_ssize_t WinListLength(PyObject *);
1060static PyObject *WinListItem(PyObject *, Py_ssize_t);
1061
1062/* Buffer list type - Implementation functions
1063 * -------------------------------------------
1064 */
1065
1066static Py_ssize_t BufListLength(PyObject *);
1067static PyObject *BufListItem(PyObject *, Py_ssize_t);
1068
1069/* Current objects type - Implementation functions
1070 * -----------------------------------------------
1071 */
1072
1073static PyObject *CurrentGetattro(PyObject *, PyObject *);
1074static int CurrentSetattro(PyObject *, PyObject *, PyObject *);
1075
1076/* Vim module - Definitions
1077 */
1078
1079static struct PyMethodDef VimMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001080 /* name, function, calling, documentation */
1081 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
1082 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
1083 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001084};
1085
1086/* Vim module - Implementation
1087 */
1088/*ARGSUSED*/
1089static PyObject * VimCommand(PyObject *self UNUSED, PyObject *args)
1090{
1091 char *cmd;
1092 PyObject *result;
1093
1094 if (!PyArg_ParseTuple(args, "s", &cmd))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001095 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001096
1097 PyErr_Clear();
1098
1099 Py_BEGIN_ALLOW_THREADS
1100 Python_Lock_Vim();
1101
1102 do_cmdline_cmd((char_u *)cmd);
1103 update_screen(VALID);
1104
1105 Python_Release_Vim();
1106 Py_END_ALLOW_THREADS
1107
1108 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001109 result = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001110 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001111 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001112
1113 Py_XINCREF(result);
1114 return result;
1115}
1116
1117#ifdef FEAT_EVAL
1118/*
1119 * Function to translate a typval_T into a PyObject; this will recursively
1120 * translate lists/dictionaries into their Python equivalents.
1121 *
1122 * The depth parameter is to avoid infinite recursion, set it to 1 when
1123 * you call VimToPython.
1124 */
1125static PyObject * VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
1126{
1127 PyObject *result;
1128 PyObject *newObj;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001129 char ptrBuf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001130
1131 /* Avoid infinite recursion */
1132 if (depth > 100)
1133 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001134 Py_INCREF(Py_None);
1135 result = Py_None;
1136 return result;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001137 }
1138
1139 /* Check if we run into a recursive loop. The item must be in lookupDict
1140 * then and we can use it again. */
1141 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001142 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001143 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001144 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
1145 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
1146 : (long_u)our_tv->vval.v_dict);
1147 result = PyDict_GetItemString(lookupDict, ptrBuf);
1148 if (result != NULL)
1149 {
1150 Py_INCREF(result);
1151 return result;
1152 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001153 }
1154
1155 if (our_tv->v_type == VAR_STRING)
1156 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001157 result = Py_BuildValue("s", our_tv->vval.v_string);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001158 }
1159 else if (our_tv->v_type == VAR_NUMBER)
1160 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001161 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001162
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001163 /* For backwards compatibility numbers are stored as strings. */
1164 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
1165 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001166 }
1167# ifdef FEAT_FLOAT
1168 else if (our_tv->v_type == VAR_FLOAT)
1169 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001170 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001171
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001172 sprintf(buf, "%f", our_tv->vval.v_float);
1173 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001174 }
1175# endif
1176 else if (our_tv->v_type == VAR_LIST)
1177 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001178 list_T *list = our_tv->vval.v_list;
1179 listitem_T *curr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001180
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001181 result = PyList_New(0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001182
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001183 if (list != NULL)
1184 {
1185 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001186
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001187 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1188 {
1189 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1190 PyList_Append(result, newObj);
1191 Py_DECREF(newObj);
1192 }
1193 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001194 }
1195 else if (our_tv->v_type == VAR_DICT)
1196 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001197 result = PyDict_New();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001198
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001199 if (our_tv->vval.v_dict != NULL)
1200 {
1201 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
1202 long_u t = ht->ht_used;
1203 hashitem_T *hi;
1204 dictitem_T *di;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001205
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001206 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001207
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001208 for (hi = ht->ht_array; t > 0; ++hi)
1209 {
1210 if (!HASHITEM_EMPTY(hi))
1211 {
1212 --t;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001213
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001214 di = dict_lookup(hi);
1215 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1216 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1217 Py_DECREF(newObj);
1218 }
1219 }
1220 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001221 }
1222 else
1223 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001224 Py_INCREF(Py_None);
1225 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001226 }
1227
1228 return result;
1229}
1230#endif
1231
1232/*ARGSUSED*/
1233static PyObject * VimEval(PyObject *self UNUSED, PyObject *args)
1234{
1235#ifdef FEAT_EVAL
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001236 char *expr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001237 typval_T *our_tv;
1238 PyObject *result;
1239 PyObject *lookup_dict;
1240
1241 if (!PyArg_ParseTuple(args, "s", &expr))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001242 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001243
1244 Py_BEGIN_ALLOW_THREADS
1245 Python_Lock_Vim();
1246 our_tv = eval_expr((char_u *)expr, NULL);
1247
1248 Python_Release_Vim();
1249 Py_END_ALLOW_THREADS
1250
1251 if (our_tv == NULL)
1252 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001253 PyErr_SetVim(_("invalid expression"));
1254 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001255 }
1256
1257 /* Convert the Vim type into a Python type. Create a dictionary that's
1258 * used to check for recursive loops. */
1259 lookup_dict = PyDict_New();
1260 result = VimToPython(our_tv, 1, lookup_dict);
1261 Py_DECREF(lookup_dict);
1262
1263
1264 Py_BEGIN_ALLOW_THREADS
1265 Python_Lock_Vim();
1266 free_tv(our_tv);
1267 Python_Release_Vim();
1268 Py_END_ALLOW_THREADS
1269
1270 return result;
1271#else
1272 PyErr_SetVim(_("expressions disabled at compile time"));
1273 return NULL;
1274#endif
1275}
1276
1277/* Common routines for buffers and line ranges
1278 * -------------------------------------------
1279 */
1280
1281static int CheckBuffer(BufferObject *this)
1282{
1283 if (this->buf == INVALID_BUFFER_VALUE)
1284 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001285 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1286 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001287 }
1288
1289 return 0;
1290}
1291
1292static PyObject * RBItem(BufferObject *self, Py_ssize_t n, Py_ssize_t start, Py_ssize_t end)
1293{
1294 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001295 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001296
1297 if (n < 0 || n > end - start)
1298 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001299 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1300 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001301 }
1302
1303 return GetBufferLine(self->buf, n+start);
1304}
1305
1306static Py_ssize_t RBAsItem(BufferObject *self, Py_ssize_t n, PyObject *val, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1307{
1308 Py_ssize_t len_change;
1309
1310 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001311 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001312
1313 if (n < 0 || n > end - start)
1314 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001315 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1316 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001317 }
1318
1319 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001320 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001321
1322 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001323 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001324
1325 return 0;
1326}
1327
1328static PyObject * RBSlice(BufferObject *self, Py_ssize_t lo, Py_ssize_t hi, Py_ssize_t start, Py_ssize_t end)
1329{
1330 Py_ssize_t size;
1331
1332 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001333 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001334
1335 size = end - start + 1;
1336
1337 if (lo < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001338 lo = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001339 else if (lo > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001340 lo = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001341 if (hi < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001342 hi = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001343 if (hi < lo)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001344 hi = lo;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001345 else if (hi > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001346 hi = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001347
1348 return GetBufferLineList(self->buf, lo+start, hi+start);
1349}
1350
1351static PyObject * RBAppend(BufferObject *self, PyObject *args, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1352{
1353 PyObject *lines;
1354 Py_ssize_t len_change;
1355 Py_ssize_t max;
1356 Py_ssize_t n;
1357
1358 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001359 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001360
1361 max = n = end - start + 1;
1362
1363 if (!PyArg_ParseTuple(args, "O|n" , &lines, &n))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001364 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001365
1366 if (n < 0 || n > max)
1367 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001368 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1369 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001370 }
1371
1372 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001373 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001374
1375 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001376 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001377
1378 Py_INCREF(Py_None);
1379 return Py_None;
1380}
1381
1382
1383static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001384 /* name, function, calling, documentation */
1385 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1386 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1387 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
1388 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001389};
1390
1391static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001392 (lenfunc) BufferLength, /* sq_length, len(x) */
1393 (binaryfunc) 0, /* sq_concat, x+y */
1394 (ssizeargfunc) 0, /* sq_repeat, x*n */
1395 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
1396 0, /* was_sq_slice, x[i:j] */
1397 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
1398 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001399 0, /* sq_contains */
1400 0, /* sq_inplace_concat */
1401 0, /* sq_inplace_repeat */
1402};
1403
1404PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001405 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001406 /* mp_subscript */ (binaryfunc)BufferSubscript,
1407 /* mp_ass_subscript */ (objobjargproc)0,
1408};
1409
1410
1411/* Buffer object - Definitions
1412 */
1413
1414static PyTypeObject BufferType;
1415
1416static PyObject * BufferNew(buf_T *buf)
1417{
1418 /* We need to handle deletion of buffers underneath us.
1419 * If we add a "b_python3_ref" field to the buf_T structure,
1420 * then we can get at it in buf_freeall() in vim. We then
1421 * need to create only ONE Python object per buffer - if
1422 * we try to create a second, just INCREF the existing one
1423 * and return it. The (single) Python object referring to
1424 * the buffer is stored in "b_python3_ref".
1425 * Question: what to do on a buf_freeall(). We'll probably
1426 * have to either delete the Python object (DECREF it to
1427 * zero - a bad idea, as it leaves dangling refs!) or
1428 * set the buf_T * value to an invalid value (-1?), which
1429 * means we need checks in all access functions... Bah.
1430 */
1431
1432 BufferObject *self;
1433
1434 if (buf->b_python3_ref != NULL)
1435 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001436 self = buf->b_python3_ref;
1437 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001438 }
1439 else
1440 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001441 self = PyObject_NEW(BufferObject, &BufferType);
1442 buf->b_python3_ref = self;
1443 if (self == NULL)
1444 return NULL;
1445 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001446 }
1447
1448 return (PyObject *)(self);
1449}
1450
1451static void BufferDestructor(PyObject *self)
1452{
1453 BufferObject *this = (BufferObject *)(self);
1454
1455 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001456 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001457}
1458
1459static PyObject * BufferGetattro(PyObject *self, PyObject*nameobj)
1460{
1461 BufferObject *this = (BufferObject *)(self);
1462
1463 char *name = "";
1464 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001465 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001466
1467 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001468 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001469
1470 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001471 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001472 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001473 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001474 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001475 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001476 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001477 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001478}
1479
1480static PyObject * BufferRepr(PyObject *self)
1481{
1482 static char repr[100];
1483 BufferObject *this = (BufferObject *)(self);
1484
1485 if (this->buf == INVALID_BUFFER_VALUE)
1486 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001487 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
1488 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001489 }
1490 else
1491 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001492 char *name = (char *)this->buf->b_fname;
1493 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001494
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001495 if (name == NULL)
1496 name = "";
1497 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001498
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001499 if (len > 35)
1500 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001501
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001502 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001503
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001504 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001505 }
1506}
1507
1508/******************/
1509
1510static Py_ssize_t BufferLength(PyObject *self)
1511{
1512 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001513 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001514
1515 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
1516}
1517
1518static PyObject * BufferItem(PyObject *self, Py_ssize_t n)
1519{
1520 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001521 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001522}
1523
1524static Py_ssize_t BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1525{
1526 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001527 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1528 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001529}
1530
1531static PyObject * BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1532{
1533 return RBSlice((BufferObject *)(self), lo, hi, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001534 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001535}
1536
1537
1538static PyObject* BufferSubscript(PyObject *self, PyObject* idx)
1539{
1540 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001541 long _idx = PyLong_AsLong(idx);
1542 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001543 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001544 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001545
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001546 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1547 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
1548 &start, &stop,
1549 &step, &slicelen) < 0) {
1550 return NULL;
1551 }
1552 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001553 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001554 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1555 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001556 }
1557}
1558
1559static PyObject * BufferAppend(PyObject *self, PyObject *args)
1560{
1561 return RBAppend((BufferObject *)(self), args, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001562 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1563 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001564}
1565
1566static PyObject * BufferMark(PyObject *self, PyObject *args)
1567{
1568 pos_T *posp;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001569 char *pmark;//test
1570 char mark;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001571 buf_T *curbuf_save;
1572
1573 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001574 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001575
1576 if (!PyArg_ParseTuple(args, "s", &pmark))//test: "c"->"s"
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001577 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001578 mark = *pmark;//test
1579
1580 curbuf_save = curbuf;
1581 curbuf = ((BufferObject *)(self))->buf;
1582 posp = getmark(mark, FALSE);
1583 curbuf = curbuf_save;
1584
1585 if (posp == NULL)
1586 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001587 PyErr_SetVim(_("invalid mark name"));
1588 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001589 }
1590
1591 /* Ckeck for keyboard interrupt */
1592 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001593 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001594
1595 if (posp->lnum <= 0)
1596 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001597 /* Or raise an error? */
1598 Py_INCREF(Py_None);
1599 return Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001600 }
1601
1602 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1603}
1604
1605static PyObject * BufferRange(PyObject *self, PyObject *args)
1606{
1607 Py_ssize_t start;
1608 Py_ssize_t end;
1609
1610 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001611 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001612
1613 if (!PyArg_ParseTuple(args, "nn", &start, &end))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001614 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001615
1616 return RangeNew(((BufferObject *)(self))->buf, start, end);
1617}
1618
1619/* Line range object - Definitions
1620 */
1621
1622static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001623 /* name, function, calling, documentation */
1624 {"append", RangeAppend, 1, "Append data to the Vim range" },
1625 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001626};
1627
1628static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001629 (lenfunc) RangeLength, /* sq_length, len(x) */
1630 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
1631 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1632 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1633 0, /* was_sq_slice, x[i:j] */
1634 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1635 0, /* sq_ass_slice, x[i:j]=v */
1636 0, /* sq_contains */
1637 0, /* sq_inplace_concat */
1638 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001639};
1640
1641PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001642 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001643 /* mp_subscript */ (binaryfunc)RangeSubscript,
1644 /* mp_ass_subscript */ (objobjargproc)0,
1645};
1646
1647static PyTypeObject RangeType;
1648
1649/* Line range object - Implementation
1650 */
1651
1652static PyObject * RangeNew(buf_T *buf, Py_ssize_t start, Py_ssize_t end)
1653{
1654 BufferObject *bufr;
1655 RangeObject *self;
1656 self = PyObject_NEW(RangeObject, &RangeType);
1657 if (self == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001658 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001659
1660 bufr = (BufferObject *)BufferNew(buf);
1661 if (bufr == NULL)
1662 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001663 Py_DECREF(self);
1664 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001665 }
1666 Py_INCREF(bufr);
1667
1668 self->buf = bufr;
1669 self->start = start;
1670 self->end = end;
1671
1672 return (PyObject *)(self);
1673}
1674
1675static void RangeDestructor(PyObject *self)
1676{
1677 Py_DECREF(((RangeObject *)(self))->buf);
1678}
1679
1680static PyObject * RangeGetattro(PyObject *self, PyObject *nameobj)
1681{
1682 char *name = "";
1683 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001684 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001685
1686 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001687 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001688 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001689 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001690 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001691 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001692}
1693
1694static PyObject * RangeRepr(PyObject *self)
1695{
1696 static char repr[100];
1697 RangeObject *this = (RangeObject *)(self);
1698
1699 if (this->buf->buf == INVALID_BUFFER_VALUE)
1700 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001701 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1702 (self));
1703 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001704 }
1705 else
1706 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001707 char *name = (char *)this->buf->buf->b_fname;
1708 int len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001709
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001710 if (name == NULL)
1711 name = "";
1712 len = (int)strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001713
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001714 if (len > 45)
1715 name = name + (45 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001716
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001717 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1718 len > 45 ? "..." : "", name,
1719 this->start, this->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001720
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001721 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001722 }
1723}
1724
1725/****************/
1726
1727static Py_ssize_t RangeLength(PyObject *self)
1728{
1729 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1730 if (CheckBuffer(((RangeObject *)(self))->buf))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001731 return -1; /* ??? */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001732
1733 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1734}
1735
1736static PyObject * RangeItem(PyObject *self, Py_ssize_t n)
1737{
1738 return RBItem(((RangeObject *)(self))->buf, n,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001739 ((RangeObject *)(self))->start,
1740 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001741}
1742
1743static Py_ssize_t RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1744{
1745 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001746 ((RangeObject *)(self))->start,
1747 ((RangeObject *)(self))->end,
1748 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001749}
1750
1751static PyObject * RangeSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1752{
1753 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001754 ((RangeObject *)(self))->start,
1755 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001756}
1757
1758static PyObject* RangeSubscript(PyObject *self, PyObject* idx)
1759{
1760 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001761 long _idx = PyLong_AsLong(idx);
1762 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001763 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001764 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001765
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001766 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1767 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1768 &start, &stop,
1769 &step, &slicelen) < 0) {
1770 return NULL;
1771 }
1772 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001773 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001774 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1775 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001776 }
1777}
1778
1779static PyObject * RangeAppend(PyObject *self, PyObject *args)
1780{
1781 return RBAppend(((RangeObject *)(self))->buf, args,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001782 ((RangeObject *)(self))->start,
1783 ((RangeObject *)(self))->end,
1784 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001785}
1786
1787/* Buffer list object - Definitions
1788 */
1789
1790typedef struct
1791{
1792 PyObject_HEAD
1793}
1794BufListObject;
1795
1796static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001797 (lenfunc) BufListLength, /* sq_length, len(x) */
1798 (binaryfunc) 0, /* sq_concat, x+y */
1799 (ssizeargfunc) 0, /* sq_repeat, x*n */
1800 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1801 0, /* was_sq_slice, x[i:j] */
1802 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1803 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001804 0, /* sq_contains */
1805 0, /* sq_inplace_concat */
1806 0, /* sq_inplace_repeat */
1807};
1808
1809static PyTypeObject BufListType;
1810
1811/* Buffer list object - Implementation
1812 */
1813
1814/*ARGSUSED*/
1815static Py_ssize_t BufListLength(PyObject *self UNUSED)
1816{
1817 buf_T *b = firstbuf;
1818 Py_ssize_t n = 0;
1819
1820 while (b)
1821 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001822 ++n;
1823 b = b->b_next;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001824 }
1825
1826 return n;
1827}
1828
1829/*ARGSUSED*/
1830static PyObject * BufListItem(PyObject *self UNUSED, Py_ssize_t n)
1831{
1832 buf_T *b;
1833
1834 for (b = firstbuf; b; b = b->b_next, --n)
1835 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001836 if (n == 0)
1837 return BufferNew(b);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001838 }
1839
1840 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1841 return NULL;
1842}
1843
1844/* Window object - Definitions
1845 */
1846
1847static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001848 /* name, function, calling, documentation */
1849 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001850};
1851
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001852static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001853
1854/* Window object - Implementation
1855 */
1856
1857static PyObject * WindowNew(win_T *win)
1858{
1859 /* We need to handle deletion of windows underneath us.
1860 * If we add a "w_python3_ref" field to the win_T structure,
1861 * then we can get at it in win_free() in vim. We then
1862 * need to create only ONE Python object per window - if
1863 * we try to create a second, just INCREF the existing one
1864 * and return it. The (single) Python object referring to
1865 * the window is stored in "w_python3_ref".
1866 * On a win_free() we set the Python object's win_T* field
1867 * to an invalid value. We trap all uses of a window
1868 * object, and reject them if the win_T* field is invalid.
1869 */
1870
1871 WindowObject *self;
1872
1873 if (win->w_python3_ref)
1874 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001875 self = win->w_python3_ref;
1876 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001877 }
1878 else
1879 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001880 self = PyObject_NEW(WindowObject, &WindowType);
1881 if (self == NULL)
1882 return NULL;
1883 self->win = win;
1884 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001885 }
1886
1887 return (PyObject *)(self);
1888}
1889
1890static void WindowDestructor(PyObject *self)
1891{
1892 WindowObject *this = (WindowObject *)(self);
1893
1894 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001895 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001896}
1897
1898static int CheckWindow(WindowObject *this)
1899{
1900 if (this->win == INVALID_WINDOW_VALUE)
1901 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001902 PyErr_SetVim(_("attempt to refer to deleted window"));
1903 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001904 }
1905
1906 return 0;
1907}
1908
1909static PyObject * WindowGetattro(PyObject *self, PyObject *nameobj)
1910{
1911 WindowObject *this = (WindowObject *)(self);
1912
1913 char *name = "";
1914 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001915 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001916
1917
1918 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001919 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001920
1921 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001922 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001923 else if (strcmp(name, "cursor") == 0)
1924 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001925 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001926
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001927 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001928 }
1929 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001930 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001931#ifdef FEAT_VERTSPLIT
1932 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001933 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001934#endif
1935 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001936 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001937 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001938 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001939}
1940
1941static int WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
1942{
1943 WindowObject *this = (WindowObject *)(self);
1944
1945 char *name = "";
1946 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001947 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001948
1949
1950 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001951 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001952
1953 if (strcmp(name, "buffer") == 0)
1954 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001955 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1956 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001957 }
1958 else if (strcmp(name, "cursor") == 0)
1959 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001960 long lnum;
1961 long col;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001962
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001963 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1964 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001965
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001966 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1967 {
1968 PyErr_SetVim(_("cursor position outside buffer"));
1969 return -1;
1970 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001971
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001972 /* Check for keyboard interrupts */
1973 if (VimErrorCheck())
1974 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001975
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001976 /* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001977
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001978 this->win->w_cursor.lnum = lnum;
1979 this->win->w_cursor.col = col;
1980 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001981
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001982 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001983 }
1984 else if (strcmp(name, "height") == 0)
1985 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001986 int height;
1987 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001988
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001989 if (!PyArg_Parse(val, "i", &height))
1990 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001991
1992#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001993 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001994#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001995 savewin = curwin;
1996 curwin = this->win;
1997 win_setheight(height);
1998 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001999
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002000 /* Check for keyboard interrupts */
2001 if (VimErrorCheck())
2002 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002003
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002004 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002005 }
2006#ifdef FEAT_VERTSPLIT
2007 else if (strcmp(name, "width") == 0)
2008 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002009 int width;
2010 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002011
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002012 if (!PyArg_Parse(val, "i", &width))
2013 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002014
2015#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002016 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002017#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002018 savewin = curwin;
2019 curwin = this->win;
2020 win_setwidth(width);
2021 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002022
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002023 /* Check for keyboard interrupts */
2024 if (VimErrorCheck())
2025 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002026
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002027 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002028 }
2029#endif
2030 else
2031 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002032 PyErr_SetString(PyExc_AttributeError, name);
2033 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002034 }
2035}
2036
2037static PyObject * WindowRepr(PyObject *self)
2038{
2039 static char repr[100];
2040 WindowObject *this = (WindowObject *)(self);
2041
2042 if (this->win == INVALID_WINDOW_VALUE)
2043 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002044 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2045 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002046 }
2047 else
2048 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002049 int i = 0;
2050 win_T *w;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002051
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002052 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
2053 ++i;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002054
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002055 if (w == NULL)
2056 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2057 (self));
2058 else
2059 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002060
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002061 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002062 }
2063}
2064
2065/* Window list object - Definitions
2066 */
2067
2068typedef struct
2069{
2070 PyObject_HEAD
2071}
2072WinListObject;
2073
2074static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002075 (lenfunc) WinListLength, /* sq_length, len(x) */
2076 (binaryfunc) 0, /* sq_concat, x+y */
2077 (ssizeargfunc) 0, /* sq_repeat, x*n */
2078 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
2079 0, /* sq_slice, x[i:j] */
2080 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
2081 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002082 0, /* sq_contains */
2083 0, /* sq_inplace_concat */
2084 0, /* sq_inplace_repeat */
2085};
2086
2087static PyTypeObject WinListType;
2088
2089/* Window list object - Implementation
2090 */
2091/*ARGSUSED*/
2092static Py_ssize_t WinListLength(PyObject *self UNUSED)
2093{
2094 win_T *w = firstwin;
2095 Py_ssize_t n = 0;
2096
2097 while (w != NULL)
2098 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002099 ++n;
2100 w = W_NEXT(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002101 }
2102
2103 return n;
2104}
2105
2106/*ARGSUSED*/
2107static PyObject * WinListItem(PyObject *self UNUSED, Py_ssize_t n)
2108{
2109 win_T *w;
2110
2111 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002112 if (n == 0)
2113 return WindowNew(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002114
2115 PyErr_SetString(PyExc_IndexError, _("no such window"));
2116 return NULL;
2117}
2118
2119/* Current items object - Definitions
2120 */
2121
2122typedef struct
2123{
2124 PyObject_HEAD
2125}
2126CurrentObject;
2127
2128static PyTypeObject CurrentType;
2129
2130/* Current items object - Implementation
2131 */
2132/*ARGSUSED*/
2133static PyObject * CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
2134{
2135 char *name = "";
2136 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002137 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002138
2139 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002140 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002141 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002142 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002143 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002144 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002145 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002146 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002147 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002148 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002149 else
2150 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002151 PyErr_SetString(PyExc_AttributeError, name);
2152 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002153 }
2154}
2155
2156/*ARGSUSED*/
2157static int CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
2158{
2159 char *name = "";
2160 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002161 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002162
2163 if (strcmp(name, "line") == 0)
2164 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002165 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
2166 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002167
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002168 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002169 }
2170 else
2171 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002172 PyErr_SetString(PyExc_AttributeError, name);
2173 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002174 }
2175}
2176
2177/* External interface
2178 */
2179
2180 void
2181python3_buffer_free(buf_T *buf)
2182{
2183 if (buf->b_python3_ref != NULL)
2184 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002185 BufferObject *bp = buf->b_python3_ref;
2186 bp->buf = INVALID_BUFFER_VALUE;
2187 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002188 }
2189}
2190
2191#if defined(FEAT_WINDOWS) || defined(PROTO)
2192 void
2193python3_window_free(win_T *win)
2194{
2195 if (win->w_python3_ref != NULL)
2196 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002197 WindowObject *wp = win->w_python3_ref;
2198 wp->win = INVALID_WINDOW_VALUE;
2199 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002200 }
2201}
2202#endif
2203
2204static BufListObject TheBufferList =
2205{
2206 PyObject_HEAD_INIT(&BufListType)
2207};
2208
2209static WinListObject TheWindowList =
2210{
2211 PyObject_HEAD_INIT(&WinListType)
2212};
2213
2214static CurrentObject TheCurrent =
2215{
2216 PyObject_HEAD_INIT(&CurrentType)
2217};
2218
2219PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
2220
2221static struct PyModuleDef vimmodule;
2222
Bram Moolenaar69154f22010-07-18 21:42:34 +02002223#ifndef PROTO
2224PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002225{
2226 PyObject *mod;
2227 /* The special value is removed from sys.path in Python3_Init(). */
2228 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
2229
2230 PyType_Ready(&BufferType);
2231 PyType_Ready(&RangeType);
2232 PyType_Ready(&WindowType);
2233 PyType_Ready(&BufListType);
2234 PyType_Ready(&WinListType);
2235 PyType_Ready(&CurrentType);
2236
2237 /* Set sys.argv[] to avoid a crash in warn(). */
2238 PySys_SetArgv(1, argv);
2239
2240 mod = PyModule_Create(&vimmodule);
2241
2242 VimError = Py_BuildValue("s", "vim.error");
2243
2244 PyModule_AddObject(mod, "error", VimError);
2245 Py_INCREF((PyObject *)(void *)&TheBufferList);
2246 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
2247 Py_INCREF((PyObject *)(void *)&TheCurrent);
2248 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
2249 Py_INCREF((PyObject *)(void *)&TheWindowList);
2250 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
2251
2252 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002253 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002254
2255 return mod;
2256}
Bram Moolenaar69154f22010-07-18 21:42:34 +02002257#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002258
2259/*************************************************************************
2260 * 4. Utility functions for handling the interface between Vim and Python.
2261 */
2262
2263
2264/* Get a list of lines from the specified buffer. The line numbers
2265 * are in Vim format (1-based). The range is from lo up to, but not
2266 * including, hi. The list is returned as a Python list of string objects.
2267 */
2268static PyObject * GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi)
2269{
2270 Py_ssize_t i;
2271 Py_ssize_t n = hi - lo;
2272 PyObject *list = PyList_New(n);
2273
2274 if (list == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002275 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002276
2277 for (i = 0; i < n; ++i)
2278 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002279 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002280
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002281 /* Error check - was the Python string creation OK? */
2282 if (str == NULL)
2283 {
2284 Py_DECREF(list);
2285 return NULL;
2286 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002287
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002288 /* Set the list item */
2289 if (PyList_SetItem(list, i, str))
2290 {
2291 Py_DECREF(str);
2292 Py_DECREF(list);
2293 return NULL;
2294 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002295 }
2296
2297 /* The ownership of the Python list is passed to the caller (ie,
2298 * the caller should Py_DECREF() the object when it is finished
2299 * with it).
2300 */
2301
2302 return list;
2303}
2304
2305/* Get a line from the specified buffer. The line number is
2306 * in Vim format (1-based). The line is returned as a Python
2307 * string object.
2308 */
2309static PyObject * GetBufferLine(buf_T *buf, Py_ssize_t n)
2310{
2311 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2312}
2313
2314/*
2315 * Check if deleting lines made the cursor position invalid.
2316 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2317 * deleted).
2318 */
2319static void py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2320{
2321 if (curwin->w_cursor.lnum >= lo)
2322 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002323 /* Adjust the cursor position if it's in/after the changed
2324 * lines. */
2325 if (curwin->w_cursor.lnum >= hi)
2326 {
2327 curwin->w_cursor.lnum += extra;
2328 check_cursor_col();
2329 }
2330 else if (extra < 0)
2331 {
2332 curwin->w_cursor.lnum = lo;
2333 check_cursor();
2334 }
2335 else
2336 check_cursor_col();
2337 changed_cline_bef_curs();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002338 }
2339 invalidate_botline();
2340}
2341
2342/* Replace a line in the specified buffer. The line number is
2343 * in Vim format (1-based). The replacement line is given as
2344 * a Python string object. The object is checked for validity
2345 * and correct format. Errors are returned as a value of FAIL.
2346 * The return value is OK on success.
2347 * If OK is returned and len_change is not NULL, *len_change
2348 * is set to the change in the buffer length.
2349 */
2350static int SetBufferLine(buf_T *buf, Py_ssize_t n, PyObject *line, Py_ssize_t *len_change)
2351{
2352 /* First of all, we check the thpe of the supplied Python object.
2353 * There are three cases:
2354 * 1. NULL, or None - this is a deletion.
2355 * 2. A string - this is a replacement.
2356 * 3. Anything else - this is an error.
2357 */
2358 if (line == Py_None || line == NULL)
2359 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002360 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002361
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002362 PyErr_Clear();
2363 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002364
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002365 if (u_savedel((linenr_T)n, 1L) == FAIL)
2366 PyErr_SetVim(_("cannot save undo information"));
2367 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2368 PyErr_SetVim(_("cannot delete line"));
2369 else
2370 {
2371 deleted_lines_mark((linenr_T)n, 1L);
2372 if (buf == curwin->w_buffer)
2373 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2374 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002375
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002376 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002377
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002378 if (PyErr_Occurred() || VimErrorCheck())
2379 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002380
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002381 if (len_change)
2382 *len_change = -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002383
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002384 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002385 }
2386 else if (PyUnicode_Check(line))
2387 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002388 char *save = StringToLine(line);
2389 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002390
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002391 if (save == NULL)
2392 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002393
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002394 /* We do not need to free "save" if ml_replace() consumes it. */
2395 PyErr_Clear();
2396 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002397
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002398 if (u_savesub((linenr_T)n) == FAIL)
2399 {
2400 PyErr_SetVim(_("cannot save undo information"));
2401 vim_free(save);
2402 }
2403 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2404 {
2405 PyErr_SetVim(_("cannot replace line"));
2406 vim_free(save);
2407 }
2408 else
2409 changed_bytes((linenr_T)n, 0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002410
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002411 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002412
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002413 /* Check that the cursor is not beyond the end of the line now. */
2414 if (buf == curwin->w_buffer)
2415 check_cursor_col();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002416
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002417 if (PyErr_Occurred() || VimErrorCheck())
2418 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002419
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002420 if (len_change)
2421 *len_change = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002422
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002423 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002424 }
2425 else
2426 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002427 PyErr_BadArgument();
2428 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002429 }
2430}
2431
2432/* Insert a number of lines into the specified buffer after the specifed line.
2433 * The line number is in Vim format (1-based). The lines to be inserted are
2434 * given as a Python list of string objects or as a single string. The lines
2435 * to be added are checked for validity and correct format. Errors are
2436 * returned as a value of FAIL. The return value is OK on success.
2437 * If OK is returned and len_change is not NULL, *len_change
2438 * is set to the change in the buffer length.
2439 */
2440static int InsertBufferLines(buf_T *buf, Py_ssize_t n, PyObject *lines, Py_ssize_t *len_change)
2441{
2442 /* First of all, we check the type of the supplied Python object.
2443 * It must be a string or a list, or the call is in error.
2444 */
2445 if (PyUnicode_Check(lines))
2446 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002447 char *str = StringToLine(lines);
2448 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002449
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002450 if (str == NULL)
2451 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002452
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002453 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002454
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002455 PyErr_Clear();
2456 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002457
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002458 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2459 PyErr_SetVim(_("cannot save undo information"));
2460 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2461 PyErr_SetVim(_("cannot insert line"));
2462 else
2463 appended_lines_mark((linenr_T)n, 1L);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002464
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002465 vim_free(str);
2466 curbuf = savebuf;
2467 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002468
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002469 if (PyErr_Occurred() || VimErrorCheck())
2470 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002471
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002472 if (len_change)
2473 *len_change = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002474
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002475 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002476 }
2477 else if (PyList_Check(lines))
2478 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002479 Py_ssize_t i;
2480 Py_ssize_t size = PyList_Size(lines);
2481 char **array;
2482 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002483
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002484 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2485 if (array == NULL)
2486 {
2487 PyErr_NoMemory();
2488 return FAIL;
2489 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002490
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002491 for (i = 0; i < size; ++i)
2492 {
2493 PyObject *line = PyList_GetItem(lines, i);
2494 array[i] = StringToLine(line);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002495
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002496 if (array[i] == NULL)
2497 {
2498 while (i)
2499 vim_free(array[--i]);
2500 vim_free(array);
2501 return FAIL;
2502 }
2503 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002504
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002505 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002506
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002507 PyErr_Clear();
2508 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002509
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002510 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2511 PyErr_SetVim(_("cannot save undo information"));
2512 else
2513 {
2514 for (i = 0; i < size; ++i)
2515 {
2516 if (ml_append((linenr_T)(n + i),
2517 (char_u *)array[i], 0, FALSE) == FAIL)
2518 {
2519 PyErr_SetVim(_("cannot insert line"));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002520
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002521 /* Free the rest of the lines */
2522 while (i < size)
2523 vim_free(array[i++]);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002524
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002525 break;
2526 }
2527 vim_free(array[i]);
2528 }
2529 if (i > 0)
2530 appended_lines_mark((linenr_T)n, (long)i);
2531 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002532
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002533 /* Free the array of lines. All of its contents have now
2534 * been freed.
2535 */
2536 vim_free(array);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002537
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002538 curbuf = savebuf;
2539 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002540
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002541 if (PyErr_Occurred() || VimErrorCheck())
2542 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002543
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002544 if (len_change)
2545 *len_change = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002546
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002547 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002548 }
2549 else
2550 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002551 PyErr_BadArgument();
2552 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002553 }
2554}
2555
2556/* Convert a Vim line into a Python string.
2557 * All internal newlines are replaced by null characters.
2558 *
2559 * On errors, the Python exception data is set, and NULL is returned.
2560 */
2561static PyObject * LineToString(const char *str)
2562{
2563 PyObject *result;
2564 Py_ssize_t len = strlen(str);
2565 char *tmp,*p;
2566
2567 tmp = (char *)alloc((unsigned)(len+1));
2568 p = tmp;
2569 if (p == NULL)
2570 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002571 PyErr_NoMemory();
2572 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002573 }
2574
2575 while (*str)
2576 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002577 if (*str == '\n')
2578 *p = '\0';
2579 else
2580 *p = *str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002581
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002582 ++p;
2583 ++str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002584 }
2585 *p = '\0';
2586
2587 result = PyUnicode_FromStringAndSize(tmp, len);
2588
2589 vim_free(tmp);
2590 return result;
2591}
2592
2593/* Convert a Python string into a Vim line.
2594 *
2595 * The result is in allocated memory. All internal nulls are replaced by
2596 * newline characters. It is an error for the string to contain newline
2597 * characters.
2598 *
2599 * On errors, the Python exception data is set, and NULL is returned.
2600 */
2601static char * StringToLine(PyObject *obj)
2602{
2603 const char *str;
2604 char *save;
2605 Py_ssize_t len;
2606 Py_ssize_t i;
2607 char *p;
2608
2609 if (obj == NULL || !PyUnicode_Check(obj))
2610 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002611 PyErr_BadArgument();
2612 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002613 }
2614
2615 str = _PyUnicode_AsString(obj);
2616 len = PyUnicode_GET_SIZE(obj);
2617
2618 /*
2619 * Error checking: String must not contain newlines, as we
2620 * are replacing a single line, and we must replace it with
2621 * a single line.
2622 * A trailing newline is removed, so that append(f.readlines()) works.
2623 */
2624 p = memchr(str, '\n', len);
2625 if (p != NULL)
2626 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002627 if (p == str + len - 1)
2628 --len;
2629 else
2630 {
2631 PyErr_SetVim(_("string cannot contain newlines"));
2632 return NULL;
2633 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002634 }
2635
2636 /* Create a copy of the string, with internal nulls replaced by
2637 * newline characters, as is the vim convention.
2638 */
2639 save = (char *)alloc((unsigned)(len+1));
2640 if (save == NULL)
2641 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002642 PyErr_NoMemory();
2643 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002644 }
2645
2646 for (i = 0; i < len; ++i)
2647 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002648 if (str[i] == '\0')
2649 save[i] = '\n';
2650 else
2651 save[i] = str[i];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002652 }
2653
2654 save[i] = '\0';
2655
2656 return save;
2657}
2658
2659/* Check to see whether a Vim error has been reported, or a keyboard
2660 * interrupt has been detected.
2661 */
2662static int VimErrorCheck(void)
2663{
2664 if (got_int)
2665 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002666 PyErr_SetNone(PyExc_KeyboardInterrupt);
2667 return 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002668 }
2669 else if (did_emsg && !PyErr_Occurred())
2670 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002671 PyErr_SetNone(VimError);
2672 return 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002673 }
2674
2675 return 0;
2676}
2677
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002678static void init_structs(void)
2679{
2680 vim_memset(&OutputType, 0, sizeof(OutputType));
2681 OutputType.tp_name = "vim.message";
2682 OutputType.tp_basicsize = sizeof(OutputObject);
2683 OutputType.tp_getattro = OutputGetattro;
2684 OutputType.tp_setattro = OutputSetattro;
2685 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
2686 OutputType.tp_doc = "vim message object";
2687 OutputType.tp_methods = OutputMethods;
2688 OutputType.tp_alloc = call_PyType_GenericAlloc;
2689 OutputType.tp_new = call_PyType_GenericNew;
2690 OutputType.tp_free = call_PyObject_Free;
2691
2692 vim_memset(&BufferType, 0, sizeof(BufferType));
2693 BufferType.tp_name = "vim.buffer";
2694 BufferType.tp_basicsize = sizeof(BufferType);
2695 BufferType.tp_dealloc = BufferDestructor;
2696 BufferType.tp_repr = BufferRepr;
2697 BufferType.tp_as_sequence = &BufferAsSeq;
2698 BufferType.tp_as_mapping = &BufferAsMapping;
2699 BufferType.tp_getattro = BufferGetattro;
2700 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
2701 BufferType.tp_doc = "vim buffer object";
2702 BufferType.tp_methods = BufferMethods;
2703 BufferType.tp_alloc = call_PyType_GenericAlloc;
2704 BufferType.tp_new = call_PyType_GenericNew;
2705 BufferType.tp_free = call_PyObject_Free;
2706
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002707 vim_memset(&WindowType, 0, sizeof(WindowType));
2708 WindowType.tp_name = "vim.window";
2709 WindowType.tp_basicsize = sizeof(WindowObject);
2710 WindowType.tp_dealloc = WindowDestructor;
2711 WindowType.tp_repr = WindowRepr;
2712 WindowType.tp_getattro = WindowGetattro;
2713 WindowType.tp_setattro = WindowSetattro;
2714 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
2715 WindowType.tp_doc = "vim Window object";
2716 WindowType.tp_methods = WindowMethods;
2717 WindowType.tp_alloc = call_PyType_GenericAlloc;
2718 WindowType.tp_new = call_PyType_GenericNew;
2719 WindowType.tp_free = call_PyObject_Free;
2720
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002721 vim_memset(&BufListType, 0, sizeof(BufListType));
2722 BufListType.tp_name = "vim.bufferlist";
2723 BufListType.tp_basicsize = sizeof(BufListObject);
2724 BufListType.tp_as_sequence = &BufListAsSeq;
2725 BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
2726 BufferType.tp_doc = "vim buffer list";
2727
2728 vim_memset(&WinListType, 0, sizeof(WinListType));
2729 WinListType.tp_name = "vim.windowlist";
2730 WinListType.tp_basicsize = sizeof(WinListType);
2731 WinListType.tp_as_sequence = &WinListAsSeq;
2732 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
2733 WinListType.tp_doc = "vim window list";
2734
2735 vim_memset(&RangeType, 0, sizeof(RangeType));
2736 RangeType.tp_name = "vim.range";
2737 RangeType.tp_basicsize = sizeof(RangeObject);
2738 RangeType.tp_dealloc = RangeDestructor;
2739 RangeType.tp_repr = RangeRepr;
2740 RangeType.tp_as_sequence = &RangeAsSeq;
2741 RangeType.tp_as_mapping = &RangeAsMapping;
2742 RangeType.tp_getattro = RangeGetattro;
2743 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
2744 RangeType.tp_doc = "vim Range object";
2745 RangeType.tp_methods = RangeMethods;
2746 RangeType.tp_alloc = call_PyType_GenericAlloc;
2747 RangeType.tp_new = call_PyType_GenericNew;
2748 RangeType.tp_free = call_PyObject_Free;
2749
2750 vim_memset(&CurrentType, 0, sizeof(CurrentType));
2751 CurrentType.tp_name = "vim.currentdata";
2752 CurrentType.tp_basicsize = sizeof(CurrentObject);
2753 CurrentType.tp_getattro = CurrentGetattro;
2754 CurrentType.tp_setattro = CurrentSetattro;
2755 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
2756 CurrentType.tp_doc = "vim current object";
2757
2758 vim_memset(&vimmodule, 0, sizeof(vimmodule));
2759 vimmodule.m_name = "vim";
2760 vimmodule.m_doc = vim_module_doc;
2761 vimmodule.m_size = -1;
2762 vimmodule.m_methods = VimMethods;
2763}