blob: 5400dc6165650ee27b19e8d34d47e73842710a63 [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
73#ifndef _WIN32
74#include <dlfcn.h>
75#define FARPROC void*
76#define HINSTANCE void*
77#define load_dll(n) dlopen((n),RTLD_LAZY)
78#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;
324
325 if (hinstPy3)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200326 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200327 hinstPy3 = load_dll(libname);
328
329 if (!hinstPy3)
330 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200331 if (verbose)
332 EMSG2(_(e_loadlib), libname);
333 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200334 }
335
336 for (i = 0; py3_funcname_table[i].ptr; ++i)
337 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200338 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
339 py3_funcname_table[i].name)) == NULL)
340 {
341 close_dll(hinstPy3);
342 hinstPy3 = 0;
343 if (verbose)
344 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
345 return FAIL;
346 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200347 }
348
349 /* load unicode functions separately as only the ucs2 or the ucs4 functions
350 * will be present in the library
351 */
352 void *ucs_from_string, *ucs_from_string_and_size;
353
354 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
355 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200356 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200357 if (!ucs_from_string || !ucs_from_string_and_size)
358 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200359 ucs_from_string = symbol_from_dll(hinstPy3,
360 "PyUnicodeUCS4_FromString");
361 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
362 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200363 }
364 if (ucs_from_string && ucs_from_string_and_size)
365 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200366 py3_PyUnicode_FromString = ucs_from_string;
367 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200368 }
369 else
370 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200371 close_dll(hinstPy3);
372 hinstPy3 = 0;
373 if (verbose)
374 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
375 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200376 }
377
378 return OK;
379}
380
381/*
382 * If python is enabled (there is installed python on Windows system) return
383 * TRUE, else FALSE.
384 */
385int python3_enabled(int verbose)
386{
387 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
388}
389
390/* Load the standard Python exceptions - don't import the symbols from the
391 * DLL, as this can cause errors (importing data symbols is not reliable).
392 */
393static void get_py3_exceptions __ARGS((void));
394
395static void get_py3_exceptions()
396{
397 PyObject *exmod = PyImport_ImportModule("builtins");
398 PyObject *exdict = PyModule_GetDict(exmod);
399 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
400 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
401 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
402 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
403 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
404 Py_XINCREF(p3imp_PyExc_AttributeError);
405 Py_XINCREF(p3imp_PyExc_IndexError);
406 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
407 Py_XINCREF(p3imp_PyExc_TypeError);
408 Py_XINCREF(p3imp_PyExc_ValueError);
409 Py_XDECREF(exmod);
410}
411#endif /* DYNAMIC_PYTHON3 */
412
413static void call_PyObject_Free(void *p)
414{
415#ifdef Py_DEBUG
416 _PyObject_DebugFree(p);
417#else
418 PyObject_Free(p);
419#endif
420}
421static PyObject* call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
422{
423 return PyType_GenericNew(type,args,kwds);
424}
425static PyObject* call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
426{
427 return PyType_GenericAlloc(type,nitems);
428}
429
430/******************************************************
431 * Internal function prototypes.
432 */
433
434static void DoPy3Command(exarg_T *, const char *);
435static Py_ssize_t RangeStart;
436static Py_ssize_t RangeEnd;
437
438static void PythonIO_Flush(void);
439static int PythonIO_Init(void);
440static void PythonIO_Fini(void);
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200441static PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200442
443/* Utility functions for the vim/python interface
444 * ----------------------------------------------
445 */
446static PyObject *GetBufferLine(buf_T *, Py_ssize_t);
447
448static int SetBufferLine(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
449static int InsertBufferLines(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
450static PyObject *GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi);
451
452static PyObject *LineToString(const char *);
453static char *StringToLine(PyObject *);
454
455static int VimErrorCheck(void);
456
457#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
458
459/******************************************************
460 * 1. Python interpreter main program.
461 */
462
463static int py3initialised = 0;
464
465
466static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
467
468/*
469 * obtain a lock on the Vim data structures
470 */
471static void Python_Lock_Vim(void)
472{
473}
474
475/*
476 * release a lock on the Vim data structures
477 */
478static void Python_Release_Vim(void)
479{
480}
481
482void python3_end()
483{
484 static int recurse = 0;
485
486 /* If a crash occurs while doing this, don't try again. */
487 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200488 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200489
490 ++recurse;
491
492#ifdef DYNAMIC_PYTHON3
493 if (hinstPy3)
494#endif
495 if (Py_IsInitialized())
496 {
497 // acquire lock before finalizing
498 pygilstate = PyGILState_Ensure();
499
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200500 PythonIO_Fini();
501 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200502 }
503
504#ifdef DYNAMIC_PYTHON3
505 end_dynamic_python3();
506#endif
507
508 --recurse;
509}
510
511static int Python3_Init(void)
512{
513 if (!py3initialised)
514 {
515#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200516 if (!python3_enabled(TRUE))
517 {
518 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
519 goto fail;
520 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200521#endif
522
523 init_structs();
524
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200525 /* initialise threads */
526 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200527
528#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200529 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200530#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200531 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200532#endif
533
534#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200535 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200536#endif
537
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200538 if (PythonIO_Init())
539 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200540
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200541 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200542
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200543 /* Remove the element from sys.path that was added because of our
544 * argv[0] value in Py3Init_vim(). Previously we used an empty
545 * string, but dependinding on the OS we then get an empty entry or
546 * the current directory in sys.path. */
547 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200548
549 // lock is created and acquired in PyEval_InitThreads() and thread
550 // state is created in Py_Initialize()
551 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
552 // (python must have threads enabled!)
553 // so the following does both: unlock GIL and save thread state in TLS
554 // without deleting thread state
555 PyGILState_Release(pygilstate);
556
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200557 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200558 }
559
560 return 0;
561
562fail:
563 /* We call PythonIO_Flush() here to print any Python errors.
564 * This is OK, as it is possible to call this function even
565 * if PythonIO_Init() has not completed successfully (it will
566 * not do anything in this case).
567 */
568 PythonIO_Flush();
569 return -1;
570}
571
572/*
573 * External interface
574 */
575static void DoPy3Command(exarg_T *eap, const char *cmd)
576{
577#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200578 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200579#endif
580#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200581 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200582#endif
583
584#if defined(MACOS) && !defined(MACOS_X_UNIX)
585 GetPort(&oldPort);
586 /* Check if the Python library is available */
587 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200588 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200589#endif
590 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200591 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200592
593 RangeStart = eap->line1;
594 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200595 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200596
597#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
598 /* Python only works properly when the LC_NUMERIC locale is "C". */
599 saved_locale = setlocale(LC_NUMERIC, NULL);
600 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200601 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200602 else
603 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200604 /* Need to make a copy, value may change when setting new locale. */
605 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
606 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200607 }
608#endif
609
610 pygilstate = PyGILState_Ensure();
611
612 PyRun_SimpleString((char *)(cmd));
613
614 PyGILState_Release(pygilstate);
615
616#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
617 if (saved_locale != NULL)
618 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200619 (void)setlocale(LC_NUMERIC, saved_locale);
620 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200621 }
622#endif
623
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200624 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200625 PythonIO_Flush();
626#if defined(MACOS) && !defined(MACOS_X_UNIX)
627 SetPort(oldPort);
628#endif
629
630theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200631 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200632}
633
634/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200635 * ":python3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200636 */
637void ex_python3(exarg_T *eap)
638{
639 char_u *script;
640
641 script = script_get(eap, eap->arg);
642 if (!eap->skip)
643 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200644 if (script == NULL)
645 DoPy3Command(eap, (char *)eap->arg);
646 else
647 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200648 }
649 vim_free(script);
650}
651
652#define BUFFER_SIZE 2048
653
654/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200655 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200656 */
657 void
658ex_py3file(exarg_T *eap)
659{
660 static char buffer[BUFFER_SIZE];
661 const char *file;
662 char *p;
663 int i;
664
665 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
666 * stdio file pointer, but Vim and the Python DLL are compiled with
667 * different options under Windows, meaning that stdio pointers aren't
668 * compatible between the two. Yuk.
669 *
670 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
671 *
672 * We need to escape any backslashes or single quotes in the file name, so that
673 * Python won't mangle the file name.
674 */
675
676 strcpy(buffer, "exec(compile(open('");
677 p = buffer + 19; /* size of "exec(compile(open('" */
678
679 for (i=0; i<2; ++i)
680 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200681 file = (char *)eap->arg;
682 while (*file && p < buffer + (BUFFER_SIZE - 3))
683 {
684 if (*file == '\\' || *file == '\'')
685 *p++ = '\\';
686 *p++ = *file++;
687 }
688 /* If we didn't finish the file name, we hit a buffer overflow */
689 if (*file != '\0')
690 return;
691 if (i==0)
692 {
693 strcpy(p,"').read(),'");
694 p += 11;
695 }
696 else
697 {
698 strcpy(p,"','exec'))");
699 p += 10;
700 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200701 }
702
703
704 /* Execute the file */
705 DoPy3Command(eap, buffer);
706}
707
708/******************************************************
709 * 2. Python output stream: writes output via [e]msg().
710 */
711
712/* Implementation functions
713 */
714
715static PyObject *OutputGetattro(PyObject *, PyObject *);
716static int OutputSetattro(PyObject *, PyObject *, PyObject *);
717
718static PyObject *OutputWrite(PyObject *, PyObject *);
719static PyObject *OutputWritelines(PyObject *, PyObject *);
720
721typedef void (*writefn)(char_u *);
722static void writer(writefn fn, char_u *str, Py_ssize_t n);
723
724/* Output object definition
725 */
726
727typedef struct
728{
729 PyObject_HEAD
730 long softspace;
731 long error;
732} OutputObject;
733
734static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200735 /* name, function, calling, documentation */
736 {"write", OutputWrite, 1, "" },
737 {"writelines", OutputWritelines, 1, "" },
738 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200739};
740
741static PyTypeObject OutputType;
742
743/*************/
744
745static PyObject * OutputGetattro(PyObject *self, PyObject *nameobj)
746{
747 char *name = "";
748 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200749 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200750
751 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200752 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200753
754 return PyObject_GenericGetAttr(self, nameobj);
755}
756
757static int OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
758{
759 char *name = "";
760 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200761 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200762
763 if (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200764 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
765 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200766 }
767
768 if (strcmp(name, "softspace") == 0)
769 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200770 if (!PyLong_Check(val)) {
771 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
772 return -1;
773 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200774
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200775 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
776 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200777 }
778
779 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
780 return -1;
781}
782
783/*************/
784
785static PyObject * OutputWrite(PyObject *self, PyObject *args)
786{
787 int len;
788 char *str;
789 int error = ((OutputObject *)(self))->error;
790
791 if (!PyArg_ParseTuple(args, "s#", &str, &len))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200792 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200793
794 Py_BEGIN_ALLOW_THREADS
795 Python_Lock_Vim();
796 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
797 Python_Release_Vim();
798 Py_END_ALLOW_THREADS
799
800 Py_INCREF(Py_None);
801 return Py_None;
802}
803
804static PyObject * OutputWritelines(PyObject *self, PyObject *args)
805{
806 Py_ssize_t n;
807 Py_ssize_t i;
808 PyObject *list;
809 int error = ((OutputObject *)(self))->error;
810
811 if (!PyArg_ParseTuple(args, "O", &list))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200812 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200813 Py_INCREF(list);
814
815 if (!PyList_Check(list)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200816 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
817 Py_DECREF(list);
818 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200819 }
820
821 n = PyList_Size(list);
822
823 for (i = 0; i < n; ++i)
824 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200825 PyObject *line = PyList_GetItem(list, i);
826 char *str;
827 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200828
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200829 if (!PyArg_Parse(line, "s#", &str, &len)) {
830 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
831 Py_DECREF(list);
832 return NULL;
833 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200834
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200835 Py_BEGIN_ALLOW_THREADS
836 Python_Lock_Vim();
837 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
838 Python_Release_Vim();
839 Py_END_ALLOW_THREADS
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200840 }
841
842 Py_DECREF(list);
843 Py_INCREF(Py_None);
844 return Py_None;
845}
846
847/* Output buffer management
848 */
849
850static char_u *buffer = NULL;
851static Py_ssize_t buffer_len = 0;
852static Py_ssize_t buffer_size = 0;
853
854static writefn old_fn = NULL;
855
856static void buffer_ensure(Py_ssize_t n)
857{
858 Py_ssize_t new_size;
859 char_u *new_buffer;
860
861 if (n < buffer_size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200862 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200863
864 new_size = buffer_size;
865 while (new_size < n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200866 new_size += 80;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200867
868 if (new_size != buffer_size)
869 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200870 new_buffer = alloc((unsigned)new_size);
871 if (new_buffer == NULL)
872 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200873
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200874 if (buffer)
875 {
876 memcpy(new_buffer, buffer, buffer_len);
877 vim_free(buffer);
878 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200879
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200880 buffer = new_buffer;
881 buffer_size = new_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200882 }
883}
884
885static void PythonIO_Flush(void)
886{
887 if (old_fn && buffer_len)
888 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200889 buffer[buffer_len] = 0;
890 old_fn(buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200891 }
892
893 buffer_len = 0;
894}
895
896static void writer(writefn fn, char_u *str, Py_ssize_t n)
897{
898 char_u *ptr;
899
900 if (fn != old_fn && old_fn != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200901 PythonIO_Flush();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200902
903 old_fn = fn;
904
905 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
906 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200907 Py_ssize_t len = ptr - str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200908
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200909 buffer_ensure(buffer_len + len + 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200910
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200911 memcpy(buffer + buffer_len, str, len);
912 buffer_len += len;
913 buffer[buffer_len] = 0;
914 fn(buffer);
915 str = ptr + 1;
916 n -= len + 1;
917 buffer_len = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200918 }
919
920 /* Put the remaining text into the buffer for later printing */
921 buffer_ensure(buffer_len + n + 1);
922 memcpy(buffer + buffer_len, str, n);
923 buffer_len += n;
924}
925
926/***************/
927
928static OutputObject Output =
929{
930 PyObject_HEAD_INIT(&OutputType)
931 0,
932 0
933};
934
935static OutputObject Error =
936{
937 PyObject_HEAD_INIT(&OutputType)
938 0,
939 1
940};
941
942static int PythonIO_Init(void)
943{
944 PyType_Ready(&OutputType);
945
946 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
947 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
948
949 if (PyErr_Occurred())
950 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200951 EMSG(_("E264: Python: Error initialising I/O objects"));
952 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200953 }
954
955 return 0;
956}
957static void PythonIO_Fini(void)
958{
959 PySys_SetObject("stdout", NULL);
960 PySys_SetObject("stderr", NULL);
961}
962
963/******************************************************
964 * 3. Implementation of the Vim module for Python
965 */
966
967/* Vim module - Implementation functions
968 * -------------------------------------
969 */
970
971static PyObject *VimError;
972
973static PyObject *VimCommand(PyObject *, PyObject *);
974static PyObject *VimEval(PyObject *, PyObject *);
975
976/* Window type - Implementation functions
977 * --------------------------------------
978 */
979
980typedef struct
981{
982 PyObject_HEAD
983 win_T *win;
984}
985WindowObject;
986
987#define INVALID_WINDOW_VALUE ((win_T *)(-1))
988
989#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
990
991static PyObject *WindowNew(win_T *);
992
993static void WindowDestructor(PyObject *);
994static PyObject *WindowGetattro(PyObject *, PyObject *);
995static int WindowSetattro(PyObject *, PyObject *, PyObject *);
996static PyObject *WindowRepr(PyObject *);
997
998/* Buffer type - Implementation functions
999 * --------------------------------------
1000 */
1001
1002typedef struct
1003{
1004 PyObject_HEAD
1005 buf_T *buf;
1006}
1007BufferObject;
1008
1009#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
1010
1011#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
1012
1013static PyObject *BufferNew (buf_T *);
1014
1015static void BufferDestructor(PyObject *);
1016
1017static PyObject *BufferGetattro(PyObject *, PyObject*);
1018static PyObject *BufferRepr(PyObject *);
1019
1020static Py_ssize_t BufferLength(PyObject *);
1021static PyObject *BufferItem(PyObject *, Py_ssize_t);
1022static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
1023static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
1024
1025static PyObject *BufferAppend(PyObject *, PyObject *);
1026static PyObject *BufferMark(PyObject *, PyObject *);
1027static PyObject *BufferRange(PyObject *, PyObject *);
1028
1029/* Line range type - Implementation functions
1030 * --------------------------------------
1031 */
1032
1033typedef struct
1034{
1035 PyObject_HEAD
1036 BufferObject *buf;
1037 Py_ssize_t start;
1038 Py_ssize_t end;
1039}
1040RangeObject;
1041
1042#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
1043
1044static PyObject *RangeNew(buf_T *, Py_ssize_t, Py_ssize_t);
1045
1046static void RangeDestructor(PyObject *);
1047static PyObject *RangeGetattro(PyObject *, PyObject *);
1048static PyObject *RangeRepr(PyObject *);
1049static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
1050
1051static Py_ssize_t RangeLength(PyObject *);
1052static PyObject *RangeItem(PyObject *, Py_ssize_t);
1053static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
1054
1055static PyObject *RangeAppend(PyObject *, PyObject *);
1056
1057/* Window list type - Implementation functions
1058 * -------------------------------------------
1059 */
1060
1061static Py_ssize_t WinListLength(PyObject *);
1062static PyObject *WinListItem(PyObject *, Py_ssize_t);
1063
1064/* Buffer list type - Implementation functions
1065 * -------------------------------------------
1066 */
1067
1068static Py_ssize_t BufListLength(PyObject *);
1069static PyObject *BufListItem(PyObject *, Py_ssize_t);
1070
1071/* Current objects type - Implementation functions
1072 * -----------------------------------------------
1073 */
1074
1075static PyObject *CurrentGetattro(PyObject *, PyObject *);
1076static int CurrentSetattro(PyObject *, PyObject *, PyObject *);
1077
1078/* Vim module - Definitions
1079 */
1080
1081static struct PyMethodDef VimMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001082 /* name, function, calling, documentation */
1083 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
1084 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
1085 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001086};
1087
1088/* Vim module - Implementation
1089 */
1090/*ARGSUSED*/
1091static PyObject * VimCommand(PyObject *self UNUSED, PyObject *args)
1092{
1093 char *cmd;
1094 PyObject *result;
1095
1096 if (!PyArg_ParseTuple(args, "s", &cmd))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001097 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001098
1099 PyErr_Clear();
1100
1101 Py_BEGIN_ALLOW_THREADS
1102 Python_Lock_Vim();
1103
1104 do_cmdline_cmd((char_u *)cmd);
1105 update_screen(VALID);
1106
1107 Python_Release_Vim();
1108 Py_END_ALLOW_THREADS
1109
1110 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001111 result = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001112 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001113 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001114
1115 Py_XINCREF(result);
1116 return result;
1117}
1118
1119#ifdef FEAT_EVAL
1120/*
1121 * Function to translate a typval_T into a PyObject; this will recursively
1122 * translate lists/dictionaries into their Python equivalents.
1123 *
1124 * The depth parameter is to avoid infinite recursion, set it to 1 when
1125 * you call VimToPython.
1126 */
1127static PyObject * VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
1128{
1129 PyObject *result;
1130 PyObject *newObj;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001131 char ptrBuf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001132
1133 /* Avoid infinite recursion */
1134 if (depth > 100)
1135 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001136 Py_INCREF(Py_None);
1137 result = Py_None;
1138 return result;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001139 }
1140
1141 /* Check if we run into a recursive loop. The item must be in lookupDict
1142 * then and we can use it again. */
1143 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001144 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001145 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001146 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
1147 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
1148 : (long_u)our_tv->vval.v_dict);
1149 result = PyDict_GetItemString(lookupDict, ptrBuf);
1150 if (result != NULL)
1151 {
1152 Py_INCREF(result);
1153 return result;
1154 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001155 }
1156
1157 if (our_tv->v_type == VAR_STRING)
1158 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001159 result = Py_BuildValue("s", our_tv->vval.v_string);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001160 }
1161 else if (our_tv->v_type == VAR_NUMBER)
1162 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001163 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001164
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001165 /* For backwards compatibility numbers are stored as strings. */
1166 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
1167 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001168 }
1169# ifdef FEAT_FLOAT
1170 else if (our_tv->v_type == VAR_FLOAT)
1171 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001172 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001173
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001174 sprintf(buf, "%f", our_tv->vval.v_float);
1175 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001176 }
1177# endif
1178 else if (our_tv->v_type == VAR_LIST)
1179 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001180 list_T *list = our_tv->vval.v_list;
1181 listitem_T *curr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001182
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001183 result = PyList_New(0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001184
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001185 if (list != NULL)
1186 {
1187 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001188
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001189 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1190 {
1191 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1192 PyList_Append(result, newObj);
1193 Py_DECREF(newObj);
1194 }
1195 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001196 }
1197 else if (our_tv->v_type == VAR_DICT)
1198 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001199 result = PyDict_New();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001200
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001201 if (our_tv->vval.v_dict != NULL)
1202 {
1203 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
1204 long_u t = ht->ht_used;
1205 hashitem_T *hi;
1206 dictitem_T *di;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001207
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001208 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001209
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001210 for (hi = ht->ht_array; t > 0; ++hi)
1211 {
1212 if (!HASHITEM_EMPTY(hi))
1213 {
1214 --t;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001215
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001216 di = dict_lookup(hi);
1217 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1218 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1219 Py_DECREF(newObj);
1220 }
1221 }
1222 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001223 }
1224 else
1225 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001226 Py_INCREF(Py_None);
1227 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001228 }
1229
1230 return result;
1231}
1232#endif
1233
1234/*ARGSUSED*/
1235static PyObject * VimEval(PyObject *self UNUSED, PyObject *args)
1236{
1237#ifdef FEAT_EVAL
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001238 char *expr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001239 typval_T *our_tv;
1240 PyObject *result;
1241 PyObject *lookup_dict;
1242
1243 if (!PyArg_ParseTuple(args, "s", &expr))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001244 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001245
1246 Py_BEGIN_ALLOW_THREADS
1247 Python_Lock_Vim();
1248 our_tv = eval_expr((char_u *)expr, NULL);
1249
1250 Python_Release_Vim();
1251 Py_END_ALLOW_THREADS
1252
1253 if (our_tv == NULL)
1254 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001255 PyErr_SetVim(_("invalid expression"));
1256 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001257 }
1258
1259 /* Convert the Vim type into a Python type. Create a dictionary that's
1260 * used to check for recursive loops. */
1261 lookup_dict = PyDict_New();
1262 result = VimToPython(our_tv, 1, lookup_dict);
1263 Py_DECREF(lookup_dict);
1264
1265
1266 Py_BEGIN_ALLOW_THREADS
1267 Python_Lock_Vim();
1268 free_tv(our_tv);
1269 Python_Release_Vim();
1270 Py_END_ALLOW_THREADS
1271
1272 return result;
1273#else
1274 PyErr_SetVim(_("expressions disabled at compile time"));
1275 return NULL;
1276#endif
1277}
1278
1279/* Common routines for buffers and line ranges
1280 * -------------------------------------------
1281 */
1282
1283static int CheckBuffer(BufferObject *this)
1284{
1285 if (this->buf == INVALID_BUFFER_VALUE)
1286 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001287 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1288 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001289 }
1290
1291 return 0;
1292}
1293
1294static PyObject * RBItem(BufferObject *self, Py_ssize_t n, Py_ssize_t start, Py_ssize_t end)
1295{
1296 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001297 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001298
1299 if (n < 0 || n > end - start)
1300 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001301 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1302 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001303 }
1304
1305 return GetBufferLine(self->buf, n+start);
1306}
1307
1308static 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)
1309{
1310 Py_ssize_t len_change;
1311
1312 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001313 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001314
1315 if (n < 0 || n > end - start)
1316 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001317 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1318 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001319 }
1320
1321 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001322 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001323
1324 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001325 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001326
1327 return 0;
1328}
1329
1330static PyObject * RBSlice(BufferObject *self, Py_ssize_t lo, Py_ssize_t hi, Py_ssize_t start, Py_ssize_t end)
1331{
1332 Py_ssize_t size;
1333
1334 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001335 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001336
1337 size = end - start + 1;
1338
1339 if (lo < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001340 lo = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001341 else if (lo > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001342 lo = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001343 if (hi < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001344 hi = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001345 if (hi < lo)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001346 hi = lo;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001347 else if (hi > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001348 hi = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001349
1350 return GetBufferLineList(self->buf, lo+start, hi+start);
1351}
1352
1353static PyObject * RBAppend(BufferObject *self, PyObject *args, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1354{
1355 PyObject *lines;
1356 Py_ssize_t len_change;
1357 Py_ssize_t max;
1358 Py_ssize_t n;
1359
1360 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001361 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001362
1363 max = n = end - start + 1;
1364
1365 if (!PyArg_ParseTuple(args, "O|n" , &lines, &n))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001366 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001367
1368 if (n < 0 || n > max)
1369 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001370 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1371 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001372 }
1373
1374 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001375 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001376
1377 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001378 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001379
1380 Py_INCREF(Py_None);
1381 return Py_None;
1382}
1383
1384
1385static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001386 /* name, function, calling, documentation */
1387 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1388 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1389 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
1390 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001391};
1392
1393static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001394 (lenfunc) BufferLength, /* sq_length, len(x) */
1395 (binaryfunc) 0, /* sq_concat, x+y */
1396 (ssizeargfunc) 0, /* sq_repeat, x*n */
1397 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
1398 0, /* was_sq_slice, x[i:j] */
1399 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
1400 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001401 0, /* sq_contains */
1402 0, /* sq_inplace_concat */
1403 0, /* sq_inplace_repeat */
1404};
1405
1406PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001407 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001408 /* mp_subscript */ (binaryfunc)BufferSubscript,
1409 /* mp_ass_subscript */ (objobjargproc)0,
1410};
1411
1412
1413/* Buffer object - Definitions
1414 */
1415
1416static PyTypeObject BufferType;
1417
1418static PyObject * BufferNew(buf_T *buf)
1419{
1420 /* We need to handle deletion of buffers underneath us.
1421 * If we add a "b_python3_ref" field to the buf_T structure,
1422 * then we can get at it in buf_freeall() in vim. We then
1423 * need to create only ONE Python object per buffer - if
1424 * we try to create a second, just INCREF the existing one
1425 * and return it. The (single) Python object referring to
1426 * the buffer is stored in "b_python3_ref".
1427 * Question: what to do on a buf_freeall(). We'll probably
1428 * have to either delete the Python object (DECREF it to
1429 * zero - a bad idea, as it leaves dangling refs!) or
1430 * set the buf_T * value to an invalid value (-1?), which
1431 * means we need checks in all access functions... Bah.
1432 */
1433
1434 BufferObject *self;
1435
1436 if (buf->b_python3_ref != NULL)
1437 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001438 self = buf->b_python3_ref;
1439 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001440 }
1441 else
1442 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001443 self = PyObject_NEW(BufferObject, &BufferType);
1444 buf->b_python3_ref = self;
1445 if (self == NULL)
1446 return NULL;
1447 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001448 }
1449
1450 return (PyObject *)(self);
1451}
1452
1453static void BufferDestructor(PyObject *self)
1454{
1455 BufferObject *this = (BufferObject *)(self);
1456
1457 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001458 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001459}
1460
1461static PyObject * BufferGetattro(PyObject *self, PyObject*nameobj)
1462{
1463 BufferObject *this = (BufferObject *)(self);
1464
1465 char *name = "";
1466 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001467 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001468
1469 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001470 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001471
1472 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001473 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001474 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001475 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001476 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001477 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001478 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001479 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001480}
1481
1482static PyObject * BufferRepr(PyObject *self)
1483{
1484 static char repr[100];
1485 BufferObject *this = (BufferObject *)(self);
1486
1487 if (this->buf == INVALID_BUFFER_VALUE)
1488 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001489 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
1490 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001491 }
1492 else
1493 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001494 char *name = (char *)this->buf->b_fname;
1495 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001496
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001497 if (name == NULL)
1498 name = "";
1499 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001500
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001501 if (len > 35)
1502 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001503
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001504 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001505
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001506 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001507 }
1508}
1509
1510/******************/
1511
1512static Py_ssize_t BufferLength(PyObject *self)
1513{
1514 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001515 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001516
1517 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
1518}
1519
1520static PyObject * BufferItem(PyObject *self, Py_ssize_t n)
1521{
1522 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001523 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001524}
1525
1526static Py_ssize_t BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1527{
1528 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001529 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1530 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001531}
1532
1533static PyObject * BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1534{
1535 return RBSlice((BufferObject *)(self), lo, hi, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001536 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001537}
1538
1539
1540static PyObject* BufferSubscript(PyObject *self, PyObject* idx)
1541{
1542 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001543 long _idx = PyLong_AsLong(idx);
1544 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001545 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001546 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001547
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001548 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1549 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
1550 &start, &stop,
1551 &step, &slicelen) < 0) {
1552 return NULL;
1553 }
1554 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001555 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001556 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1557 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001558 }
1559}
1560
1561static PyObject * BufferAppend(PyObject *self, PyObject *args)
1562{
1563 return RBAppend((BufferObject *)(self), args, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001564 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1565 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001566}
1567
1568static PyObject * BufferMark(PyObject *self, PyObject *args)
1569{
1570 pos_T *posp;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001571 char *pmark;//test
1572 char mark;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001573 buf_T *curbuf_save;
1574
1575 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001576 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001577
1578 if (!PyArg_ParseTuple(args, "s", &pmark))//test: "c"->"s"
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001579 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001580 mark = *pmark;//test
1581
1582 curbuf_save = curbuf;
1583 curbuf = ((BufferObject *)(self))->buf;
1584 posp = getmark(mark, FALSE);
1585 curbuf = curbuf_save;
1586
1587 if (posp == NULL)
1588 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001589 PyErr_SetVim(_("invalid mark name"));
1590 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001591 }
1592
1593 /* Ckeck for keyboard interrupt */
1594 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001595 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001596
1597 if (posp->lnum <= 0)
1598 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001599 /* Or raise an error? */
1600 Py_INCREF(Py_None);
1601 return Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001602 }
1603
1604 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1605}
1606
1607static PyObject * BufferRange(PyObject *self, PyObject *args)
1608{
1609 Py_ssize_t start;
1610 Py_ssize_t end;
1611
1612 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001613 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001614
1615 if (!PyArg_ParseTuple(args, "nn", &start, &end))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001616 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001617
1618 return RangeNew(((BufferObject *)(self))->buf, start, end);
1619}
1620
1621/* Line range object - Definitions
1622 */
1623
1624static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001625 /* name, function, calling, documentation */
1626 {"append", RangeAppend, 1, "Append data to the Vim range" },
1627 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001628};
1629
1630static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001631 (lenfunc) RangeLength, /* sq_length, len(x) */
1632 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
1633 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1634 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1635 0, /* was_sq_slice, x[i:j] */
1636 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1637 0, /* sq_ass_slice, x[i:j]=v */
1638 0, /* sq_contains */
1639 0, /* sq_inplace_concat */
1640 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001641};
1642
1643PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001644 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001645 /* mp_subscript */ (binaryfunc)RangeSubscript,
1646 /* mp_ass_subscript */ (objobjargproc)0,
1647};
1648
1649static PyTypeObject RangeType;
1650
1651/* Line range object - Implementation
1652 */
1653
1654static PyObject * RangeNew(buf_T *buf, Py_ssize_t start, Py_ssize_t end)
1655{
1656 BufferObject *bufr;
1657 RangeObject *self;
1658 self = PyObject_NEW(RangeObject, &RangeType);
1659 if (self == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001660 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001661
1662 bufr = (BufferObject *)BufferNew(buf);
1663 if (bufr == NULL)
1664 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001665 Py_DECREF(self);
1666 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001667 }
1668 Py_INCREF(bufr);
1669
1670 self->buf = bufr;
1671 self->start = start;
1672 self->end = end;
1673
1674 return (PyObject *)(self);
1675}
1676
1677static void RangeDestructor(PyObject *self)
1678{
1679 Py_DECREF(((RangeObject *)(self))->buf);
1680}
1681
1682static PyObject * RangeGetattro(PyObject *self, PyObject *nameobj)
1683{
1684 char *name = "";
1685 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001686 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001687
1688 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001689 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001690 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001691 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001692 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001693 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001694}
1695
1696static PyObject * RangeRepr(PyObject *self)
1697{
1698 static char repr[100];
1699 RangeObject *this = (RangeObject *)(self);
1700
1701 if (this->buf->buf == INVALID_BUFFER_VALUE)
1702 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001703 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1704 (self));
1705 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001706 }
1707 else
1708 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001709 char *name = (char *)this->buf->buf->b_fname;
1710 int len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001711
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001712 if (name == NULL)
1713 name = "";
1714 len = (int)strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001715
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001716 if (len > 45)
1717 name = name + (45 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001718
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001719 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1720 len > 45 ? "..." : "", name,
1721 this->start, this->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001722
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001723 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001724 }
1725}
1726
1727/****************/
1728
1729static Py_ssize_t RangeLength(PyObject *self)
1730{
1731 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1732 if (CheckBuffer(((RangeObject *)(self))->buf))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001733 return -1; /* ??? */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001734
1735 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1736}
1737
1738static PyObject * RangeItem(PyObject *self, Py_ssize_t n)
1739{
1740 return RBItem(((RangeObject *)(self))->buf, n,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001741 ((RangeObject *)(self))->start,
1742 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001743}
1744
1745static Py_ssize_t RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
1746{
1747 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001748 ((RangeObject *)(self))->start,
1749 ((RangeObject *)(self))->end,
1750 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001751}
1752
1753static PyObject * RangeSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1754{
1755 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001756 ((RangeObject *)(self))->start,
1757 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001758}
1759
1760static PyObject* RangeSubscript(PyObject *self, PyObject* idx)
1761{
1762 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001763 long _idx = PyLong_AsLong(idx);
1764 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001765 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001766 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001767
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001768 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1769 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1770 &start, &stop,
1771 &step, &slicelen) < 0) {
1772 return NULL;
1773 }
1774 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001775 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001776 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1777 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001778 }
1779}
1780
1781static PyObject * RangeAppend(PyObject *self, PyObject *args)
1782{
1783 return RBAppend(((RangeObject *)(self))->buf, args,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001784 ((RangeObject *)(self))->start,
1785 ((RangeObject *)(self))->end,
1786 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001787}
1788
1789/* Buffer list object - Definitions
1790 */
1791
1792typedef struct
1793{
1794 PyObject_HEAD
1795}
1796BufListObject;
1797
1798static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001799 (lenfunc) BufListLength, /* sq_length, len(x) */
1800 (binaryfunc) 0, /* sq_concat, x+y */
1801 (ssizeargfunc) 0, /* sq_repeat, x*n */
1802 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1803 0, /* was_sq_slice, x[i:j] */
1804 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1805 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001806 0, /* sq_contains */
1807 0, /* sq_inplace_concat */
1808 0, /* sq_inplace_repeat */
1809};
1810
1811static PyTypeObject BufListType;
1812
1813/* Buffer list object - Implementation
1814 */
1815
1816/*ARGSUSED*/
1817static Py_ssize_t BufListLength(PyObject *self UNUSED)
1818{
1819 buf_T *b = firstbuf;
1820 Py_ssize_t n = 0;
1821
1822 while (b)
1823 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001824 ++n;
1825 b = b->b_next;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001826 }
1827
1828 return n;
1829}
1830
1831/*ARGSUSED*/
1832static PyObject * BufListItem(PyObject *self UNUSED, Py_ssize_t n)
1833{
1834 buf_T *b;
1835
1836 for (b = firstbuf; b; b = b->b_next, --n)
1837 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001838 if (n == 0)
1839 return BufferNew(b);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001840 }
1841
1842 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1843 return NULL;
1844}
1845
1846/* Window object - Definitions
1847 */
1848
1849static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001850 /* name, function, calling, documentation */
1851 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001852};
1853
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001854static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001855
1856/* Window object - Implementation
1857 */
1858
1859static PyObject * WindowNew(win_T *win)
1860{
1861 /* We need to handle deletion of windows underneath us.
1862 * If we add a "w_python3_ref" field to the win_T structure,
1863 * then we can get at it in win_free() in vim. We then
1864 * need to create only ONE Python object per window - if
1865 * we try to create a second, just INCREF the existing one
1866 * and return it. The (single) Python object referring to
1867 * the window is stored in "w_python3_ref".
1868 * On a win_free() we set the Python object's win_T* field
1869 * to an invalid value. We trap all uses of a window
1870 * object, and reject them if the win_T* field is invalid.
1871 */
1872
1873 WindowObject *self;
1874
1875 if (win->w_python3_ref)
1876 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001877 self = win->w_python3_ref;
1878 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001879 }
1880 else
1881 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001882 self = PyObject_NEW(WindowObject, &WindowType);
1883 if (self == NULL)
1884 return NULL;
1885 self->win = win;
1886 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001887 }
1888
1889 return (PyObject *)(self);
1890}
1891
1892static void WindowDestructor(PyObject *self)
1893{
1894 WindowObject *this = (WindowObject *)(self);
1895
1896 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001897 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001898}
1899
1900static int CheckWindow(WindowObject *this)
1901{
1902 if (this->win == INVALID_WINDOW_VALUE)
1903 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001904 PyErr_SetVim(_("attempt to refer to deleted window"));
1905 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001906 }
1907
1908 return 0;
1909}
1910
1911static PyObject * WindowGetattro(PyObject *self, PyObject *nameobj)
1912{
1913 WindowObject *this = (WindowObject *)(self);
1914
1915 char *name = "";
1916 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001917 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001918
1919
1920 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001921 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001922
1923 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001924 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001925 else if (strcmp(name, "cursor") == 0)
1926 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001927 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001928
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001929 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001930 }
1931 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001932 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001933#ifdef FEAT_VERTSPLIT
1934 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001935 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001936#endif
1937 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001938 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001939 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001940 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001941}
1942
1943static int WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
1944{
1945 WindowObject *this = (WindowObject *)(self);
1946
1947 char *name = "";
1948 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001949 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001950
1951
1952 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001953 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001954
1955 if (strcmp(name, "buffer") == 0)
1956 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001957 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1958 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001959 }
1960 else if (strcmp(name, "cursor") == 0)
1961 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001962 long lnum;
1963 long col;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001964
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001965 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1966 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001967
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001968 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1969 {
1970 PyErr_SetVim(_("cursor position outside buffer"));
1971 return -1;
1972 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001973
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001974 /* Check for keyboard interrupts */
1975 if (VimErrorCheck())
1976 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001977
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001978 /* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001979
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001980 this->win->w_cursor.lnum = lnum;
1981 this->win->w_cursor.col = col;
1982 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001983
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001984 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001985 }
1986 else if (strcmp(name, "height") == 0)
1987 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001988 int height;
1989 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001990
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001991 if (!PyArg_Parse(val, "i", &height))
1992 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001993
1994#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001995 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001996#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001997 savewin = curwin;
1998 curwin = this->win;
1999 win_setheight(height);
2000 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002001
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002002 /* Check for keyboard interrupts */
2003 if (VimErrorCheck())
2004 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002005
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002006 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002007 }
2008#ifdef FEAT_VERTSPLIT
2009 else if (strcmp(name, "width") == 0)
2010 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002011 int width;
2012 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002013
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002014 if (!PyArg_Parse(val, "i", &width))
2015 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002016
2017#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002018 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002019#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002020 savewin = curwin;
2021 curwin = this->win;
2022 win_setwidth(width);
2023 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002024
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002025 /* Check for keyboard interrupts */
2026 if (VimErrorCheck())
2027 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002028
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002029 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002030 }
2031#endif
2032 else
2033 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002034 PyErr_SetString(PyExc_AttributeError, name);
2035 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002036 }
2037}
2038
2039static PyObject * WindowRepr(PyObject *self)
2040{
2041 static char repr[100];
2042 WindowObject *this = (WindowObject *)(self);
2043
2044 if (this->win == INVALID_WINDOW_VALUE)
2045 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002046 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2047 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002048 }
2049 else
2050 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002051 int i = 0;
2052 win_T *w;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002053
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002054 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
2055 ++i;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002056
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002057 if (w == NULL)
2058 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2059 (self));
2060 else
2061 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002062
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002063 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002064 }
2065}
2066
2067/* Window list object - Definitions
2068 */
2069
2070typedef struct
2071{
2072 PyObject_HEAD
2073}
2074WinListObject;
2075
2076static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002077 (lenfunc) WinListLength, /* sq_length, len(x) */
2078 (binaryfunc) 0, /* sq_concat, x+y */
2079 (ssizeargfunc) 0, /* sq_repeat, x*n */
2080 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
2081 0, /* sq_slice, x[i:j] */
2082 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
2083 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002084 0, /* sq_contains */
2085 0, /* sq_inplace_concat */
2086 0, /* sq_inplace_repeat */
2087};
2088
2089static PyTypeObject WinListType;
2090
2091/* Window list object - Implementation
2092 */
2093/*ARGSUSED*/
2094static Py_ssize_t WinListLength(PyObject *self UNUSED)
2095{
2096 win_T *w = firstwin;
2097 Py_ssize_t n = 0;
2098
2099 while (w != NULL)
2100 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002101 ++n;
2102 w = W_NEXT(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002103 }
2104
2105 return n;
2106}
2107
2108/*ARGSUSED*/
2109static PyObject * WinListItem(PyObject *self UNUSED, Py_ssize_t n)
2110{
2111 win_T *w;
2112
2113 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002114 if (n == 0)
2115 return WindowNew(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002116
2117 PyErr_SetString(PyExc_IndexError, _("no such window"));
2118 return NULL;
2119}
2120
2121/* Current items object - Definitions
2122 */
2123
2124typedef struct
2125{
2126 PyObject_HEAD
2127}
2128CurrentObject;
2129
2130static PyTypeObject CurrentType;
2131
2132/* Current items object - Implementation
2133 */
2134/*ARGSUSED*/
2135static PyObject * CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
2136{
2137 char *name = "";
2138 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002139 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002140
2141 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002142 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002143 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002144 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002145 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002146 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002147 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002148 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002149 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002150 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002151 else
2152 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002153 PyErr_SetString(PyExc_AttributeError, name);
2154 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002155 }
2156}
2157
2158/*ARGSUSED*/
2159static int CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
2160{
2161 char *name = "";
2162 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002163 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002164
2165 if (strcmp(name, "line") == 0)
2166 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002167 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
2168 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002169
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002170 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002171 }
2172 else
2173 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002174 PyErr_SetString(PyExc_AttributeError, name);
2175 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002176 }
2177}
2178
2179/* External interface
2180 */
2181
2182 void
2183python3_buffer_free(buf_T *buf)
2184{
2185 if (buf->b_python3_ref != NULL)
2186 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002187 BufferObject *bp = buf->b_python3_ref;
2188 bp->buf = INVALID_BUFFER_VALUE;
2189 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002190 }
2191}
2192
2193#if defined(FEAT_WINDOWS) || defined(PROTO)
2194 void
2195python3_window_free(win_T *win)
2196{
2197 if (win->w_python3_ref != NULL)
2198 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002199 WindowObject *wp = win->w_python3_ref;
2200 wp->win = INVALID_WINDOW_VALUE;
2201 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002202 }
2203}
2204#endif
2205
2206static BufListObject TheBufferList =
2207{
2208 PyObject_HEAD_INIT(&BufListType)
2209};
2210
2211static WinListObject TheWindowList =
2212{
2213 PyObject_HEAD_INIT(&WinListType)
2214};
2215
2216static CurrentObject TheCurrent =
2217{
2218 PyObject_HEAD_INIT(&CurrentType)
2219};
2220
2221PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
2222
2223static struct PyModuleDef vimmodule;
2224
Bram Moolenaar6df6f472010-07-18 18:04:50 +02002225static PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002226{
2227 PyObject *mod;
2228 /* The special value is removed from sys.path in Python3_Init(). */
2229 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
2230
2231 PyType_Ready(&BufferType);
2232 PyType_Ready(&RangeType);
2233 PyType_Ready(&WindowType);
2234 PyType_Ready(&BufListType);
2235 PyType_Ready(&WinListType);
2236 PyType_Ready(&CurrentType);
2237
2238 /* Set sys.argv[] to avoid a crash in warn(). */
2239 PySys_SetArgv(1, argv);
2240
2241 mod = PyModule_Create(&vimmodule);
2242
2243 VimError = Py_BuildValue("s", "vim.error");
2244
2245 PyModule_AddObject(mod, "error", VimError);
2246 Py_INCREF((PyObject *)(void *)&TheBufferList);
2247 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
2248 Py_INCREF((PyObject *)(void *)&TheCurrent);
2249 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
2250 Py_INCREF((PyObject *)(void *)&TheWindowList);
2251 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
2252
2253 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002254 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002255
2256 return mod;
2257}
2258
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}