blob: 0b3a0527b9be08085aa9d593d8bbb784e4a0c803 [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
Bram Moolenaard68554d2010-07-25 13:43:20 +020037#if defined(_WIN32) && defined(HAVE_FCNTL_H)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020038# 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
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020071#define PyInt Py_ssize_t
72
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020073#if defined(DYNAMIC_PYTHON3)
74
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020075#ifndef WIN3264
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020076#include <dlfcn.h>
77#define FARPROC void*
78#define HINSTANCE void*
Bram Moolenaarfa5d1e62010-07-22 21:44:13 +020079#define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +020080#define close_dll dlclose
81#define symbol_from_dll dlsym
82#else
83#define load_dll LoadLibrary
84#define close_dll FreeLibrary
85#define symbol_from_dll GetProcAddress
86#endif
87/*
88 * Wrapper defines
89 */
90#undef PyArg_Parse
91# define PyArg_Parse py3_PyArg_Parse
92#undef PyArg_ParseTuple
93# define PyArg_ParseTuple py3_PyArg_ParseTuple
94# define PyDict_SetItemString py3_PyDict_SetItemString
95# define PyErr_BadArgument py3_PyErr_BadArgument
96# define PyErr_Clear py3_PyErr_Clear
97# define PyErr_NoMemory py3_PyErr_NoMemory
98# define PyErr_Occurred py3_PyErr_Occurred
99# define PyErr_SetNone py3_PyErr_SetNone
100# define PyErr_SetString py3_PyErr_SetString
101# define PyEval_InitThreads py3_PyEval_InitThreads
102# define PyEval_RestoreThread py3_PyEval_RestoreThread
103# define PyEval_SaveThread py3_PyEval_SaveThread
104# define PyGILState_Ensure py3_PyGILState_Ensure
105# define PyGILState_Release py3_PyGILState_Release
106# define PyLong_AsLong py3_PyLong_AsLong
107# define PyLong_FromLong py3_PyLong_FromLong
108# define PyList_GetItem py3_PyList_GetItem
109# define PyList_Append py3_PyList_Append
110# define PyList_New py3_PyList_New
111# define PyList_SetItem py3_PyList_SetItem
112# define PyList_Size py3_PyList_Size
113# define PySlice_GetIndicesEx py3_PySlice_GetIndicesEx
114# define PyImport_ImportModule py3_PyImport_ImportModule
115# define PyObject_Init py3__PyObject_Init
116# define PyDict_New py3_PyDict_New
117# define PyDict_GetItemString py3_PyDict_GetItemString
118# define PyModule_GetDict py3_PyModule_GetDict
119#undef PyRun_SimpleString
120# define PyRun_SimpleString py3_PyRun_SimpleString
121# define PySys_SetObject py3_PySys_SetObject
122# define PySys_SetArgv py3_PySys_SetArgv
123# define PyType_Type (*py3_PyType_Type)
124# define PyType_Ready py3_PyType_Ready
125#undef Py_BuildValue
126# define Py_BuildValue py3_Py_BuildValue
127# define Py_Initialize py3_Py_Initialize
128# define Py_Finalize py3_Py_Finalize
129# define Py_IsInitialized py3_Py_IsInitialized
130# define _Py_NoneStruct (*py3__Py_NoneStruct)
131# define PyModule_AddObject py3_PyModule_AddObject
132# define PyImport_AppendInittab py3_PyImport_AppendInittab
133# define _PyUnicode_AsString py3__PyUnicode_AsString
134# define PyObject_GenericGetAttr py3_PyObject_GenericGetAttr
135# define PySlice_Type (*py3_PySlice_Type)
136#ifdef Py_DEBUG
137 # define _Py_NegativeRefcount py3__Py_NegativeRefcount
138 # define _Py_RefTotal (*py3__Py_RefTotal)
139 # define _Py_Dealloc py3__Py_Dealloc
140 # define _PyObject_DebugMalloc py3__PyObject_DebugMalloc
141 # define _PyObject_DebugFree py3__PyObject_DebugFree
142#else
143 # define PyObject_Malloc py3_PyObject_Malloc
144 # define PyObject_Free py3_PyObject_Free
145#endif
146# define PyType_GenericAlloc py3_PyType_GenericAlloc
147# define PyType_GenericNew py3_PyType_GenericNew
148# define PyModule_Create2 py3_PyModule_Create2
149#undef PyUnicode_FromString
150# define PyUnicode_FromString py3_PyUnicode_FromString
151#undef PyUnicode_FromStringAndSize
152# define PyUnicode_FromStringAndSize py3_PyUnicode_FromStringAndSize
153
154#ifdef Py_DEBUG
155#undef PyObject_NEW
156#define PyObject_NEW(type, typeobj) \
157( (type *) PyObject_Init( \
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200158 (PyObject *) _PyObject_DebugMalloc( _PyObject_SIZE(typeobj) ), (typeobj)) )
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200159#endif
160/*
161 * Pointers for dynamic link
162 */
163static int (*py3_PySys_SetArgv)(int, wchar_t **);
164static void (*py3_Py_Initialize)(void);
165static PyObject* (*py3_PyList_New)(Py_ssize_t size);
166static PyGILState_STATE (*py3_PyGILState_Ensure)(void);
167static void (*py3_PyGILState_Release)(PyGILState_STATE);
168static int (*py3_PySys_SetObject)(char *, PyObject *);
169static PyObject* (*py3_PyList_Append)(PyObject *, PyObject *);
170static Py_ssize_t (*py3_PyList_Size)(PyObject *);
171static int (*py3_PySlice_GetIndicesEx)(PySliceObject *r, Py_ssize_t length,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200172 Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200173static PyObject* (*py3_PyErr_NoMemory)(void);
174static void (*py3_Py_Finalize)(void);
175static void (*py3_PyErr_SetString)(PyObject *, const char *);
176static int (*py3_PyRun_SimpleString)(char *);
177static PyObject* (*py3_PyList_GetItem)(PyObject *, Py_ssize_t);
178static PyObject* (*py3_PyImport_ImportModule)(const char *);
179static int (*py3_PyErr_BadArgument)(void);
180static PyTypeObject* py3_PyType_Type;
181static PyObject* (*py3_PyErr_Occurred)(void);
182static PyObject* (*py3_PyModule_GetDict)(PyObject *);
183static int (*py3_PyList_SetItem)(PyObject *, Py_ssize_t, PyObject *);
184static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
185static PyObject* (*py3_PyLong_FromLong)(long);
186static PyObject* (*py3_PyDict_New)(void);
187static PyObject* (*py3_Py_BuildValue)(char *, ...);
188static int (*py3_PyType_Ready)(PyTypeObject *type);
189static int (*py3_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
190static PyObject* (*py3_PyUnicode_FromString)(const char *u);
191static PyObject* (*py3_PyUnicode_FromStringAndSize)(const char *u, Py_ssize_t size);
192static long (*py3_PyLong_AsLong)(PyObject *);
193static void (*py3_PyErr_SetNone)(PyObject *);
194static void (*py3_PyEval_InitThreads)(void);
195static void(*py3_PyEval_RestoreThread)(PyThreadState *);
196static PyThreadState*(*py3_PyEval_SaveThread)(void);
197static int (*py3_PyArg_Parse)(PyObject *, char *, ...);
198static int (*py3_PyArg_ParseTuple)(PyObject *, char *, ...);
199static int (*py3_Py_IsInitialized)(void);
200static void (*py3_PyErr_Clear)(void);
201static PyObject*(*py3__PyObject_Init)(PyObject *, PyTypeObject *);
202static PyObject* py3__Py_NoneStruct;
203static int (*py3_PyModule_AddObject)(PyObject *m, const char *name, PyObject *o);
204static int (*py3_PyImport_AppendInittab)(const char *name, PyObject* (*initfunc)(void));
205static char* (*py3__PyUnicode_AsString)(PyObject *unicode);
206static PyObject* (*py3_PyObject_GenericGetAttr)(PyObject *obj, PyObject *name);
207static PyObject* (*py3_PyModule_Create2)(struct PyModuleDef* module, int module_api_version);
208static PyObject* (*py3_PyType_GenericAlloc)(PyTypeObject *type, Py_ssize_t nitems);
209static PyObject* (*py3_PyType_GenericNew)(PyTypeObject *type, PyObject *args, PyObject *kwds);
210static PyTypeObject* py3_PySlice_Type;
211#ifdef Py_DEBUG
212 static void (*py3__Py_NegativeRefcount)(const char *fname, int lineno, PyObject *op);
213 static Py_ssize_t* py3__Py_RefTotal;
214 static void (*py3__Py_Dealloc)(PyObject *obj);
215 static void (*py3__PyObject_DebugFree)(void*);
216 static void* (*py3__PyObject_DebugMalloc)(size_t);
217#else
218 static void (*py3_PyObject_Free)(void*);
219 static void* (*py3_PyObject_Malloc)(size_t);
220#endif
221
222static HINSTANCE hinstPy3 = 0; /* Instance of python.dll */
223
224/* Imported exception objects */
225static PyObject *p3imp_PyExc_AttributeError;
226static PyObject *p3imp_PyExc_IndexError;
227static PyObject *p3imp_PyExc_KeyboardInterrupt;
228static PyObject *p3imp_PyExc_TypeError;
229static PyObject *p3imp_PyExc_ValueError;
230
231# define PyExc_AttributeError p3imp_PyExc_AttributeError
232# define PyExc_IndexError p3imp_PyExc_IndexError
233# define PyExc_KeyboardInterrupt p3imp_PyExc_KeyboardInterrupt
234# define PyExc_TypeError p3imp_PyExc_TypeError
235# define PyExc_ValueError p3imp_PyExc_ValueError
236
237/*
238 * Table of name to function pointer of python.
239 */
240# define PYTHON_PROC FARPROC
241static struct
242{
243 char *name;
244 PYTHON_PROC *ptr;
245} py3_funcname_table[] =
246{
247 {"PySys_SetArgv", (PYTHON_PROC*)&py3_PySys_SetArgv},
248 {"Py_Initialize", (PYTHON_PROC*)&py3_Py_Initialize},
249 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
250 {"PyList_New", (PYTHON_PROC*)&py3_PyList_New},
251 {"PyGILState_Ensure", (PYTHON_PROC*)&py3_PyGILState_Ensure},
252 {"PyGILState_Release", (PYTHON_PROC*)&py3_PyGILState_Release},
253 {"PySys_SetObject", (PYTHON_PROC*)&py3_PySys_SetObject},
254 {"PyList_Append", (PYTHON_PROC*)&py3_PyList_Append},
255 {"PyList_Size", (PYTHON_PROC*)&py3_PyList_Size},
256 {"PySlice_GetIndicesEx", (PYTHON_PROC*)&py3_PySlice_GetIndicesEx},
257 {"PyErr_NoMemory", (PYTHON_PROC*)&py3_PyErr_NoMemory},
258 {"Py_Finalize", (PYTHON_PROC*)&py3_Py_Finalize},
259 {"PyErr_SetString", (PYTHON_PROC*)&py3_PyErr_SetString},
260 {"PyRun_SimpleString", (PYTHON_PROC*)&py3_PyRun_SimpleString},
261 {"PyList_GetItem", (PYTHON_PROC*)&py3_PyList_GetItem},
262 {"PyImport_ImportModule", (PYTHON_PROC*)&py3_PyImport_ImportModule},
263 {"PyErr_BadArgument", (PYTHON_PROC*)&py3_PyErr_BadArgument},
264 {"PyType_Type", (PYTHON_PROC*)&py3_PyType_Type},
265 {"PyErr_Occurred", (PYTHON_PROC*)&py3_PyErr_Occurred},
266 {"PyModule_GetDict", (PYTHON_PROC*)&py3_PyModule_GetDict},
267 {"PyList_SetItem", (PYTHON_PROC*)&py3_PyList_SetItem},
268 {"PyDict_GetItemString", (PYTHON_PROC*)&py3_PyDict_GetItemString},
269 {"PyLong_FromLong", (PYTHON_PROC*)&py3_PyLong_FromLong},
270 {"PyDict_New", (PYTHON_PROC*)&py3_PyDict_New},
271 {"Py_BuildValue", (PYTHON_PROC*)&py3_Py_BuildValue},
272 {"PyType_Ready", (PYTHON_PROC*)&py3_PyType_Ready},
273 {"PyDict_SetItemString", (PYTHON_PROC*)&py3_PyDict_SetItemString},
274 {"PyLong_AsLong", (PYTHON_PROC*)&py3_PyLong_AsLong},
275 {"PyErr_SetNone", (PYTHON_PROC*)&py3_PyErr_SetNone},
276 {"PyEval_InitThreads", (PYTHON_PROC*)&py3_PyEval_InitThreads},
277 {"PyEval_RestoreThread", (PYTHON_PROC*)&py3_PyEval_RestoreThread},
278 {"PyEval_SaveThread", (PYTHON_PROC*)&py3_PyEval_SaveThread},
279 {"PyArg_Parse", (PYTHON_PROC*)&py3_PyArg_Parse},
280 {"PyArg_ParseTuple", (PYTHON_PROC*)&py3_PyArg_ParseTuple},
281 {"Py_IsInitialized", (PYTHON_PROC*)&py3_Py_IsInitialized},
282 {"_Py_NoneStruct", (PYTHON_PROC*)&py3__Py_NoneStruct},
283 {"PyErr_Clear", (PYTHON_PROC*)&py3_PyErr_Clear},
284 {"PyObject_Init", (PYTHON_PROC*)&py3__PyObject_Init},
285 {"PyModule_AddObject", (PYTHON_PROC*)&py3_PyModule_AddObject},
286 {"PyImport_AppendInittab", (PYTHON_PROC*)&py3_PyImport_AppendInittab},
287 {"_PyUnicode_AsString", (PYTHON_PROC*)&py3__PyUnicode_AsString},
288 {"PyObject_GenericGetAttr", (PYTHON_PROC*)&py3_PyObject_GenericGetAttr},
289 {"PyModule_Create2", (PYTHON_PROC*)&py3_PyModule_Create2},
290 {"PyType_GenericAlloc", (PYTHON_PROC*)&py3_PyType_GenericAlloc},
291 {"PyType_GenericNew", (PYTHON_PROC*)&py3_PyType_GenericNew},
292 {"PySlice_Type", (PYTHON_PROC*)&py3_PySlice_Type},
293#ifdef Py_DEBUG
294 {"_Py_NegativeRefcount", (PYTHON_PROC*)&py3__Py_NegativeRefcount},
295 {"_Py_RefTotal", (PYTHON_PROC*)&py3__Py_RefTotal},
296 {"_Py_Dealloc", (PYTHON_PROC*)&py3__Py_Dealloc},
297 {"_PyObject_DebugFree", (PYTHON_PROC*)&py3__PyObject_DebugFree},
298 {"_PyObject_DebugMalloc", (PYTHON_PROC*)&py3__PyObject_DebugMalloc},
299#else
300 {"PyObject_Malloc", (PYTHON_PROC*)&py3_PyObject_Malloc},
301 {"PyObject_Free", (PYTHON_PROC*)&py3_PyObject_Free},
302#endif
303 {"", NULL},
304};
305
306/*
307 * Free python.dll
308 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200309 static void
310end_dynamic_python3(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200311{
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200312 if (hinstPy3 != 0)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200313 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200314 close_dll(hinstPy3);
315 hinstPy3 = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200316 }
317}
318
319/*
320 * Load library and get all pointers.
321 * Parameter 'libname' provides name of DLL.
322 * Return OK or FAIL.
323 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200324 static int
325py3_runtime_link_init(char *libname, int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200326{
327 int i;
Bram Moolenaar69154f22010-07-18 21:42:34 +0200328 void *ucs_from_string, *ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200329
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200330#if defined(UNIX) && defined(FEAT_PYTHON)
331 /* Can't have Python and Python3 loaded at the same time, it may cause a
332 * crash. */
333 if (python_loaded())
334 {
335 EMSG(_("E999: Python: Cannot use :py and :py3 in one session"));
336 return FAIL;
337 }
338#endif
339
340 if (hinstPy3 != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200341 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200342 hinstPy3 = load_dll(libname);
343
344 if (!hinstPy3)
345 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200346 if (verbose)
347 EMSG2(_(e_loadlib), libname);
348 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200349 }
350
351 for (i = 0; py3_funcname_table[i].ptr; ++i)
352 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200353 if ((*py3_funcname_table[i].ptr = symbol_from_dll(hinstPy3,
354 py3_funcname_table[i].name)) == NULL)
355 {
356 close_dll(hinstPy3);
357 hinstPy3 = 0;
358 if (verbose)
359 EMSG2(_(e_loadfunc), py3_funcname_table[i].name);
360 return FAIL;
361 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200362 }
363
Bram Moolenaar69154f22010-07-18 21:42:34 +0200364 /* Load unicode functions separately as only the ucs2 or the ucs4 functions
365 * will be present in the library. */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200366 ucs_from_string = symbol_from_dll(hinstPy3, "PyUnicodeUCS2_FromString");
367 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200368 "PyUnicodeUCS2_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200369 if (!ucs_from_string || !ucs_from_string_and_size)
370 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200371 ucs_from_string = symbol_from_dll(hinstPy3,
372 "PyUnicodeUCS4_FromString");
373 ucs_from_string_and_size = symbol_from_dll(hinstPy3,
374 "PyUnicodeUCS4_FromStringAndSize");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200375 }
376 if (ucs_from_string && ucs_from_string_and_size)
377 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200378 py3_PyUnicode_FromString = ucs_from_string;
379 py3_PyUnicode_FromStringAndSize = ucs_from_string_and_size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200380 }
381 else
382 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200383 close_dll(hinstPy3);
384 hinstPy3 = 0;
385 if (verbose)
386 EMSG2(_(e_loadfunc), "PyUnicode_UCSX_*");
387 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200388 }
389
390 return OK;
391}
392
393/*
394 * If python is enabled (there is installed python on Windows system) return
395 * TRUE, else FALSE.
396 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200397 int
398python3_enabled(int verbose)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200399{
400 return py3_runtime_link_init(DYNAMIC_PYTHON3_DLL, verbose) == OK;
401}
402
403/* Load the standard Python exceptions - don't import the symbols from the
404 * DLL, as this can cause errors (importing data symbols is not reliable).
405 */
406static void get_py3_exceptions __ARGS((void));
407
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200408 static void
409get_py3_exceptions()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200410{
411 PyObject *exmod = PyImport_ImportModule("builtins");
412 PyObject *exdict = PyModule_GetDict(exmod);
413 p3imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
414 p3imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
415 p3imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
416 p3imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
417 p3imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
418 Py_XINCREF(p3imp_PyExc_AttributeError);
419 Py_XINCREF(p3imp_PyExc_IndexError);
420 Py_XINCREF(p3imp_PyExc_KeyboardInterrupt);
421 Py_XINCREF(p3imp_PyExc_TypeError);
422 Py_XINCREF(p3imp_PyExc_ValueError);
423 Py_XDECREF(exmod);
424}
425#endif /* DYNAMIC_PYTHON3 */
426
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200427/*
428 * Include the code shared with if_python.c
429 */
430#include "if_py_both.h"
431
432 static void
433call_PyObject_Free(void *p)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200434{
435#ifdef Py_DEBUG
436 _PyObject_DebugFree(p);
437#else
438 PyObject_Free(p);
439#endif
440}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200441
442 static PyObject *
443call_PyType_GenericNew(PyTypeObject *type, PyObject *args, PyObject *kwds)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200444{
445 return PyType_GenericNew(type,args,kwds);
446}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200447
448 static PyObject *
449call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200450{
451 return PyType_GenericAlloc(type,nitems);
452}
453
454/******************************************************
455 * Internal function prototypes.
456 */
457
458static void DoPy3Command(exarg_T *, const char *);
459static Py_ssize_t RangeStart;
460static Py_ssize_t RangeEnd;
461
462static void PythonIO_Flush(void);
463static int PythonIO_Init(void);
464static void PythonIO_Fini(void);
Bram Moolenaar69154f22010-07-18 21:42:34 +0200465PyMODINIT_FUNC Py3Init_vim(void);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200466
467/* Utility functions for the vim/python interface
468 * ----------------------------------------------
469 */
470static PyObject *GetBufferLine(buf_T *, Py_ssize_t);
471
472static int SetBufferLine(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
473static int InsertBufferLines(buf_T *, Py_ssize_t, PyObject *, Py_ssize_t*);
474static PyObject *GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi);
475
476static PyObject *LineToString(const char *);
477static char *StringToLine(PyObject *);
478
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200479#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
480
481/******************************************************
482 * 1. Python interpreter main program.
483 */
484
485static int py3initialised = 0;
486
487
488static PyGILState_STATE pygilstate = PyGILState_UNLOCKED;
489
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200490 void
491python3_end()
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200492{
493 static int recurse = 0;
494
495 /* If a crash occurs while doing this, don't try again. */
496 if (recurse != 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200497 return;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200498
499 ++recurse;
500
501#ifdef DYNAMIC_PYTHON3
502 if (hinstPy3)
503#endif
504 if (Py_IsInitialized())
505 {
506 // acquire lock before finalizing
507 pygilstate = PyGILState_Ensure();
508
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200509 PythonIO_Fini();
510 Py_Finalize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200511 }
512
513#ifdef DYNAMIC_PYTHON3
514 end_dynamic_python3();
515#endif
516
517 --recurse;
518}
519
Bram Moolenaar4c3a3262010-07-24 15:42:14 +0200520#if (defined(DYNAMIC_PYTHON) && defined(FEAT_PYTHON)) || defined(PROTO)
521 int
522python3_loaded()
523{
524 return (hinstPy3 != 0);
525}
526#endif
527
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200528 static int
529Python3_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200530{
531 if (!py3initialised)
532 {
533#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200534 if (!python3_enabled(TRUE))
535 {
536 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
537 goto fail;
538 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200539#endif
540
541 init_structs();
542
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200543 /* initialise threads */
544 PyEval_InitThreads();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200545
546#if !defined(MACOS) || defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200547 Py_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200548#else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200549 PyMac_Initialize();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200550#endif
551
552#ifdef DYNAMIC_PYTHON3
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200553 get_py3_exceptions();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200554#endif
555
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200556 if (PythonIO_Init())
557 goto fail;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200558
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200559 PyImport_AppendInittab("vim", Py3Init_vim);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200560
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200561 /* Remove the element from sys.path that was added because of our
562 * argv[0] value in Py3Init_vim(). Previously we used an empty
563 * string, but dependinding on the OS we then get an empty entry or
564 * the current directory in sys.path. */
565 PyRun_SimpleString("import sys; sys.path = list(filter(lambda x: x != '/must>not&exist', sys.path))");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200566
567 // lock is created and acquired in PyEval_InitThreads() and thread
568 // state is created in Py_Initialize()
569 // there _PyGILState_NoteThreadState() also sets gilcounter to 1
570 // (python must have threads enabled!)
571 // so the following does both: unlock GIL and save thread state in TLS
572 // without deleting thread state
573 PyGILState_Release(pygilstate);
574
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200575 py3initialised = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200576 }
577
578 return 0;
579
580fail:
581 /* We call PythonIO_Flush() here to print any Python errors.
582 * This is OK, as it is possible to call this function even
583 * if PythonIO_Init() has not completed successfully (it will
584 * not do anything in this case).
585 */
586 PythonIO_Flush();
587 return -1;
588}
589
590/*
591 * External interface
592 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200593 static void
594DoPy3Command(exarg_T *eap, const char *cmd)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200595{
596#if defined(MACOS) && !defined(MACOS_X_UNIX)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200597 GrafPtr oldPort;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200598#endif
599#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200600 char *saved_locale;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200601#endif
602
603#if defined(MACOS) && !defined(MACOS_X_UNIX)
604 GetPort(&oldPort);
605 /* Check if the Python library is available */
606 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200607 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200608#endif
609 if (Python3_Init())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200610 goto theend;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200611
612 RangeStart = eap->line1;
613 RangeEnd = eap->line2;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200614 Python_Release_Vim(); /* leave vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200615
616#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
617 /* Python only works properly when the LC_NUMERIC locale is "C". */
618 saved_locale = setlocale(LC_NUMERIC, NULL);
619 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200620 saved_locale = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200621 else
622 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200623 /* Need to make a copy, value may change when setting new locale. */
624 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
625 (void)setlocale(LC_NUMERIC, "C");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200626 }
627#endif
628
629 pygilstate = PyGILState_Ensure();
630
631 PyRun_SimpleString((char *)(cmd));
632
633 PyGILState_Release(pygilstate);
634
635#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
636 if (saved_locale != NULL)
637 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200638 (void)setlocale(LC_NUMERIC, saved_locale);
639 vim_free(saved_locale);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200640 }
641#endif
642
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200643 Python_Lock_Vim(); /* enter vim */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200644 PythonIO_Flush();
645#if defined(MACOS) && !defined(MACOS_X_UNIX)
646 SetPort(oldPort);
647#endif
648
649theend:
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200650 return; /* keeps lint happy */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200651}
652
653/*
Bram Moolenaar368373e2010-07-19 20:46:22 +0200654 * ":py3"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200655 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200656 void
657ex_py3(exarg_T *eap)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200658{
659 char_u *script;
660
661 script = script_get(eap, eap->arg);
662 if (!eap->skip)
663 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200664 if (script == NULL)
665 DoPy3Command(eap, (char *)eap->arg);
666 else
667 DoPy3Command(eap, (char *)script);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200668 }
669 vim_free(script);
670}
671
672#define BUFFER_SIZE 2048
673
674/*
Bram Moolenaar6df6f472010-07-18 18:04:50 +0200675 * ":py3file"
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200676 */
677 void
678ex_py3file(exarg_T *eap)
679{
680 static char buffer[BUFFER_SIZE];
681 const char *file;
682 char *p;
683 int i;
684
685 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
686 * stdio file pointer, but Vim and the Python DLL are compiled with
687 * different options under Windows, meaning that stdio pointers aren't
688 * compatible between the two. Yuk.
689 *
690 * construct: exec(compile(open('a_filename').read(), 'a_filename', 'exec'))
691 *
692 * We need to escape any backslashes or single quotes in the file name, so that
693 * Python won't mangle the file name.
694 */
695
696 strcpy(buffer, "exec(compile(open('");
697 p = buffer + 19; /* size of "exec(compile(open('" */
698
699 for (i=0; i<2; ++i)
700 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200701 file = (char *)eap->arg;
702 while (*file && p < buffer + (BUFFER_SIZE - 3))
703 {
704 if (*file == '\\' || *file == '\'')
705 *p++ = '\\';
706 *p++ = *file++;
707 }
708 /* If we didn't finish the file name, we hit a buffer overflow */
709 if (*file != '\0')
710 return;
711 if (i==0)
712 {
713 strcpy(p,"').read(),'");
714 p += 11;
715 }
716 else
717 {
718 strcpy(p,"','exec'))");
719 p += 10;
720 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200721 }
722
723
724 /* Execute the file */
725 DoPy3Command(eap, buffer);
726}
727
728/******************************************************
729 * 2. Python output stream: writes output via [e]msg().
730 */
731
732/* Implementation functions
733 */
734
735static PyObject *OutputGetattro(PyObject *, PyObject *);
736static int OutputSetattro(PyObject *, PyObject *, PyObject *);
737
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200738/*************/
739
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200740 static PyObject *
741OutputGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200742{
743 char *name = "";
744 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200745 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200746
747 if (strcmp(name, "softspace") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200748 return PyLong_FromLong(((OutputObject *)(self))->softspace);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200749
750 return PyObject_GenericGetAttr(self, nameobj);
751}
752
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200753 static int
754OutputSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200755{
756 char *name = "";
757 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200758 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200759
760 if (val == NULL) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200761 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
762 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200763 }
764
765 if (strcmp(name, "softspace") == 0)
766 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200767 if (!PyLong_Check(val)) {
768 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
769 return -1;
770 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200771
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200772 ((OutputObject *)(self))->softspace = PyLong_AsLong(val);
773 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200774 }
775
776 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
777 return -1;
778}
779
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200780/***************/
781
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200782 static int
783PythonIO_Init(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200784{
785 PyType_Ready(&OutputType);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200786 return PythonIO_Init_io();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200787}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200788
789 static void
790PythonIO_Fini(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200791{
792 PySys_SetObject("stdout", NULL);
793 PySys_SetObject("stderr", NULL);
794}
795
796/******************************************************
797 * 3. Implementation of the Vim module for Python
798 */
799
800/* Vim module - Implementation functions
801 * -------------------------------------
802 */
803
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200804static PyObject *VimCommand(PyObject *, PyObject *);
805static PyObject *VimEval(PyObject *, PyObject *);
806
807/* Window type - Implementation functions
808 * --------------------------------------
809 */
810
811typedef struct
812{
813 PyObject_HEAD
814 win_T *win;
815}
816WindowObject;
817
818#define INVALID_WINDOW_VALUE ((win_T *)(-1))
819
820#define WindowType_Check(obj) ((obj)->ob_base.ob_type == &WindowType)
821
822static PyObject *WindowNew(win_T *);
823
824static void WindowDestructor(PyObject *);
825static PyObject *WindowGetattro(PyObject *, PyObject *);
826static int WindowSetattro(PyObject *, PyObject *, PyObject *);
827static PyObject *WindowRepr(PyObject *);
828
829/* Buffer type - Implementation functions
830 * --------------------------------------
831 */
832
833typedef struct
834{
835 PyObject_HEAD
836 buf_T *buf;
837}
838BufferObject;
839
840#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
841
842#define BufferType_Check(obj) ((obj)->ob_base.ob_type == &BufferType)
843
844static PyObject *BufferNew (buf_T *);
845
846static void BufferDestructor(PyObject *);
847
848static PyObject *BufferGetattro(PyObject *, PyObject*);
849static PyObject *BufferRepr(PyObject *);
850
851static Py_ssize_t BufferLength(PyObject *);
852static PyObject *BufferItem(PyObject *, Py_ssize_t);
853static Py_ssize_t BufferAsItem(PyObject *, Py_ssize_t, PyObject *);
854static PyObject* BufferSubscript(PyObject *self, PyObject* idx);
855
856static PyObject *BufferAppend(PyObject *, PyObject *);
857static PyObject *BufferMark(PyObject *, PyObject *);
858static PyObject *BufferRange(PyObject *, PyObject *);
859
860/* Line range type - Implementation functions
861 * --------------------------------------
862 */
863
864typedef struct
865{
866 PyObject_HEAD
867 BufferObject *buf;
868 Py_ssize_t start;
869 Py_ssize_t end;
870}
871RangeObject;
872
873#define RangeType_Check(obj) ((obj)->ob_base.ob_type == &RangeType)
874
875static PyObject *RangeNew(buf_T *, Py_ssize_t, Py_ssize_t);
876
877static void RangeDestructor(PyObject *);
878static PyObject *RangeGetattro(PyObject *, PyObject *);
879static PyObject *RangeRepr(PyObject *);
880static PyObject* RangeSubscript(PyObject *self, PyObject* idx);
881
882static Py_ssize_t RangeLength(PyObject *);
883static PyObject *RangeItem(PyObject *, Py_ssize_t);
884static Py_ssize_t RangeAsItem(PyObject *, Py_ssize_t, PyObject *);
885
886static PyObject *RangeAppend(PyObject *, PyObject *);
887
888/* Window list type - Implementation functions
889 * -------------------------------------------
890 */
891
892static Py_ssize_t WinListLength(PyObject *);
893static PyObject *WinListItem(PyObject *, Py_ssize_t);
894
895/* Buffer list type - Implementation functions
896 * -------------------------------------------
897 */
898
899static Py_ssize_t BufListLength(PyObject *);
900static PyObject *BufListItem(PyObject *, Py_ssize_t);
901
902/* Current objects type - Implementation functions
903 * -----------------------------------------------
904 */
905
906static PyObject *CurrentGetattro(PyObject *, PyObject *);
907static int CurrentSetattro(PyObject *, PyObject *, PyObject *);
908
909/* Vim module - Definitions
910 */
911
912static struct PyMethodDef VimMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200913 /* name, function, calling, documentation */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200914 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200915 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
916 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200917};
918
919/* Vim module - Implementation
920 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200921 static PyObject *
922VimCommand(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200923{
924 char *cmd;
925 PyObject *result;
926
927 if (!PyArg_ParseTuple(args, "s", &cmd))
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200928 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200929
930 PyErr_Clear();
931
932 Py_BEGIN_ALLOW_THREADS
933 Python_Lock_Vim();
934
935 do_cmdline_cmd((char_u *)cmd);
936 update_screen(VALID);
937
938 Python_Release_Vim();
939 Py_END_ALLOW_THREADS
940
941 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200942 result = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200943 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200944 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200945
946 Py_XINCREF(result);
947 return result;
948}
949
950#ifdef FEAT_EVAL
951/*
952 * Function to translate a typval_T into a PyObject; this will recursively
953 * translate lists/dictionaries into their Python equivalents.
954 *
955 * The depth parameter is to avoid infinite recursion, set it to 1 when
956 * you call VimToPython.
957 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200958 static PyObject *
959VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200960{
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200961 PyObject *result;
962 PyObject *newObj;
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200963 char ptrBuf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200964
965 /* Avoid infinite recursion */
966 if (depth > 100)
967 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200968 Py_INCREF(Py_None);
969 result = Py_None;
970 return result;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200971 }
972
973 /* Check if we run into a recursive loop. The item must be in lookupDict
974 * then and we can use it again. */
975 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200976 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200977 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200978 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
979 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
980 : (long_u)our_tv->vval.v_dict);
981 result = PyDict_GetItemString(lookupDict, ptrBuf);
982 if (result != NULL)
983 {
984 Py_INCREF(result);
985 return result;
986 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200987 }
988
989 if (our_tv->v_type == VAR_STRING)
990 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200991 result = Py_BuildValue("s", our_tv->vval.v_string);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200992 }
993 else if (our_tv->v_type == VAR_NUMBER)
994 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200995 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +0200996
Bram Moolenaar55d5c032010-07-17 23:52:29 +0200997 /* For backwards compatibility numbers are stored as strings. */
998 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
999 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001000 }
1001# ifdef FEAT_FLOAT
1002 else if (our_tv->v_type == VAR_FLOAT)
1003 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001004 char buf[NUMBUFLEN];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001005
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001006 sprintf(buf, "%f", our_tv->vval.v_float);
1007 result = Py_BuildValue("s", buf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001008 }
1009# endif
1010 else if (our_tv->v_type == VAR_LIST)
1011 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001012 list_T *list = our_tv->vval.v_list;
1013 listitem_T *curr;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001014
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001015 result = PyList_New(0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001016
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001017 if (list != NULL)
1018 {
1019 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001020
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001021 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
1022 {
1023 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
1024 PyList_Append(result, newObj);
1025 Py_DECREF(newObj);
1026 }
1027 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001028 }
1029 else if (our_tv->v_type == VAR_DICT)
1030 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001031 result = PyDict_New();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001032
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001033 if (our_tv->vval.v_dict != NULL)
1034 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001035 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
1036 long_u todo = ht->ht_used;
1037 hashitem_T *hi;
1038 dictitem_T *di;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001039
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001040 PyDict_SetItemString(lookupDict, ptrBuf, result);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001041
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001042 for (hi = ht->ht_array; todo > 0; ++hi)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001043 {
1044 if (!HASHITEM_EMPTY(hi))
1045 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001046 --todo;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001047
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001048 di = dict_lookup(hi);
1049 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
1050 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
1051 Py_DECREF(newObj);
1052 }
1053 }
1054 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001055 }
1056 else
1057 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001058 Py_INCREF(Py_None);
1059 result = Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001060 }
1061
1062 return result;
1063}
1064#endif
1065
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001066 static PyObject *
1067VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001068{
1069#ifdef FEAT_EVAL
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001070 char *expr;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001071 typval_T *our_tv;
1072 PyObject *result;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001073 PyObject *lookup_dict;
1074
1075 if (!PyArg_ParseTuple(args, "s", &expr))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001076 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001077
1078 Py_BEGIN_ALLOW_THREADS
1079 Python_Lock_Vim();
1080 our_tv = eval_expr((char_u *)expr, NULL);
1081
1082 Python_Release_Vim();
1083 Py_END_ALLOW_THREADS
1084
1085 if (our_tv == NULL)
1086 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001087 PyErr_SetVim(_("invalid expression"));
1088 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001089 }
1090
1091 /* Convert the Vim type into a Python type. Create a dictionary that's
1092 * used to check for recursive loops. */
1093 lookup_dict = PyDict_New();
1094 result = VimToPython(our_tv, 1, lookup_dict);
1095 Py_DECREF(lookup_dict);
1096
1097
1098 Py_BEGIN_ALLOW_THREADS
1099 Python_Lock_Vim();
1100 free_tv(our_tv);
1101 Python_Release_Vim();
1102 Py_END_ALLOW_THREADS
1103
1104 return result;
1105#else
1106 PyErr_SetVim(_("expressions disabled at compile time"));
1107 return NULL;
1108#endif
1109}
1110
1111/* Common routines for buffers and line ranges
1112 * -------------------------------------------
1113 */
1114
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001115 static int
1116CheckBuffer(BufferObject *this)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001117{
1118 if (this->buf == INVALID_BUFFER_VALUE)
1119 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001120 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1121 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001122 }
1123
1124 return 0;
1125}
1126
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001127 static PyObject *
1128RBItem(BufferObject *self, Py_ssize_t n, Py_ssize_t start, Py_ssize_t end)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001129{
1130 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001131 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001132
1133 if (n < 0 || n > end - start)
1134 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001135 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1136 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001137 }
1138
1139 return GetBufferLine(self->buf, n+start);
1140}
1141
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001142 static PyObject *
1143RBSlice(BufferObject *self, Py_ssize_t lo, Py_ssize_t hi, Py_ssize_t start, Py_ssize_t end)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001144{
1145 Py_ssize_t size;
1146
1147 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001148 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001149
1150 size = end - start + 1;
1151
1152 if (lo < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001153 lo = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001154 else if (lo > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001155 lo = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001156 if (hi < 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001157 hi = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001158 if (hi < lo)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001159 hi = lo;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001160 else if (hi > size)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001161 hi = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001162
1163 return GetBufferLineList(self->buf, lo+start, hi+start);
1164}
1165
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001166 static Py_ssize_t
1167RBAsItem(BufferObject *self, Py_ssize_t n, PyObject *val, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
1168{
1169 Py_ssize_t len_change;
1170
1171 if (CheckBuffer(self))
1172 return -1;
1173
1174 if (n < 0 || n > end - start)
1175 {
1176 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1177 return -1;
1178 }
1179
1180 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1181 return -1;
1182
1183 if (new_end)
1184 *new_end = end + len_change;
1185
1186 return 0;
1187}
1188
1189 static PyObject *
1190RBAppend(BufferObject *self, PyObject *args, Py_ssize_t start, Py_ssize_t end, Py_ssize_t *new_end)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001191{
1192 PyObject *lines;
1193 Py_ssize_t len_change;
1194 Py_ssize_t max;
1195 Py_ssize_t n;
1196
1197 if (CheckBuffer(self))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001198 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001199
1200 max = n = end - start + 1;
1201
1202 if (!PyArg_ParseTuple(args, "O|n" , &lines, &n))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001203 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001204
1205 if (n < 0 || n > max)
1206 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001207 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1208 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001209 }
1210
1211 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001212 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001213
1214 if (new_end)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001215 *new_end = end + len_change;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001216
1217 Py_INCREF(Py_None);
1218 return Py_None;
1219}
1220
1221
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001222/* Buffer object - Definitions
1223 */
1224
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001225static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001226 /* name, function, calling, documentation */
1227 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1228 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1229 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
1230 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001231};
1232
1233static PySequenceMethods BufferAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001234 (lenfunc) BufferLength, /* sq_length, len(x) */
1235 (binaryfunc) 0, /* sq_concat, x+y */
1236 (ssizeargfunc) 0, /* sq_repeat, x*n */
1237 (ssizeargfunc) BufferItem, /* sq_item, x[i] */
1238 0, /* was_sq_slice, x[i:j] */
1239 (ssizeobjargproc) BufferAsItem, /* sq_ass_item, x[i]=v */
1240 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001241 0, /* sq_contains */
1242 0, /* sq_inplace_concat */
1243 0, /* sq_inplace_repeat */
1244};
1245
1246PyMappingMethods BufferAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001247 /* mp_length */ (lenfunc)BufferLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001248 /* mp_subscript */ (binaryfunc)BufferSubscript,
1249 /* mp_ass_subscript */ (objobjargproc)0,
1250};
1251
1252
1253/* Buffer object - Definitions
1254 */
1255
1256static PyTypeObject BufferType;
1257
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001258 static PyObject *
1259BufferNew(buf_T *buf)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001260{
1261 /* We need to handle deletion of buffers underneath us.
1262 * If we add a "b_python3_ref" field to the buf_T structure,
1263 * then we can get at it in buf_freeall() in vim. We then
1264 * need to create only ONE Python object per buffer - if
1265 * we try to create a second, just INCREF the existing one
1266 * and return it. The (single) Python object referring to
1267 * the buffer is stored in "b_python3_ref".
1268 * Question: what to do on a buf_freeall(). We'll probably
1269 * have to either delete the Python object (DECREF it to
1270 * zero - a bad idea, as it leaves dangling refs!) or
1271 * set the buf_T * value to an invalid value (-1?), which
1272 * means we need checks in all access functions... Bah.
1273 */
1274
1275 BufferObject *self;
1276
1277 if (buf->b_python3_ref != NULL)
1278 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001279 self = buf->b_python3_ref;
1280 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001281 }
1282 else
1283 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001284 self = PyObject_NEW(BufferObject, &BufferType);
1285 buf->b_python3_ref = self;
1286 if (self == NULL)
1287 return NULL;
1288 self->buf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001289 }
1290
1291 return (PyObject *)(self);
1292}
1293
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001294 static void
1295BufferDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001296{
1297 BufferObject *this = (BufferObject *)(self);
1298
1299 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001300 this->buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001301}
1302
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001303 static PyObject *
1304BufferGetattro(PyObject *self, PyObject*nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001305{
1306 BufferObject *this = (BufferObject *)(self);
1307
1308 char *name = "";
1309 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001310 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001311
1312 if (CheckBuffer(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001313 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001314
1315 if (strcmp(name, "name") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001316 return Py_BuildValue("s", this->buf->b_ffname);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001317 else if (strcmp(name, "number") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001318 return Py_BuildValue("n", this->buf->b_fnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001319 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001320 return Py_BuildValue("[ss]", "name", "number");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001321 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001322 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001323}
1324
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001325 static PyObject *
1326BufferRepr(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001327{
1328 static char repr[100];
1329 BufferObject *this = (BufferObject *)(self);
1330
1331 if (this->buf == INVALID_BUFFER_VALUE)
1332 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001333 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
1334 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001335 }
1336 else
1337 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001338 char *name = (char *)this->buf->b_fname;
1339 Py_ssize_t len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001340
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001341 if (name == NULL)
1342 name = "";
1343 len = strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001344
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001345 if (len > 35)
1346 name = name + (35 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001347
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001348 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001349
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001350 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001351 }
1352}
1353
1354/******************/
1355
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001356 static Py_ssize_t
1357BufferLength(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001358{
1359 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001360 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001361
1362 return (Py_ssize_t)(((BufferObject *)(self))->buf->b_ml.ml_line_count);
1363}
1364
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001365 static PyObject *
1366BufferItem(PyObject *self, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001367{
1368 return RBItem((BufferObject *)(self), n, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001369 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001370}
1371
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001372 static PyObject *
1373BufferSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
1374{
1375 return RBSlice((BufferObject *)(self), lo, hi, 1,
1376 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1377}
1378
1379 static Py_ssize_t
1380BufferAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001381{
1382 return RBAsItem((BufferObject *)(self), n, val, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001383 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1384 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001385}
1386
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001387
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001388 static PyObject *
1389BufferSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001390{
1391 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001392 long _idx = PyLong_AsLong(idx);
1393 return BufferItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001394 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001395 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001396
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001397 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1398 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count+1,
1399 &start, &stop,
1400 &step, &slicelen) < 0) {
1401 return NULL;
1402 }
1403 return BufferSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001404 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001405 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1406 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001407 }
1408}
1409
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001410 static PyObject *
1411BufferAppend(PyObject *self, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001412{
1413 return RBAppend((BufferObject *)(self), args, 1,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001414 (Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1415 NULL);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001416}
1417
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001418 static PyObject *
1419BufferMark(PyObject *self, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001420{
1421 pos_T *posp;
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001422 char *pmark;//test
1423 char mark;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001424 buf_T *curbuf_save;
1425
1426 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001427 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001428
1429 if (!PyArg_ParseTuple(args, "s", &pmark))//test: "c"->"s"
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001430 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001431 mark = *pmark;//test
1432
1433 curbuf_save = curbuf;
1434 curbuf = ((BufferObject *)(self))->buf;
1435 posp = getmark(mark, FALSE);
1436 curbuf = curbuf_save;
1437
1438 if (posp == NULL)
1439 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001440 PyErr_SetVim(_("invalid mark name"));
1441 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001442 }
1443
1444 /* Ckeck for keyboard interrupt */
1445 if (VimErrorCheck())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001446 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001447
1448 if (posp->lnum <= 0)
1449 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001450 /* Or raise an error? */
1451 Py_INCREF(Py_None);
1452 return Py_None;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001453 }
1454
1455 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1456}
1457
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001458 static PyObject *
1459BufferRange(PyObject *self, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001460{
1461 Py_ssize_t start;
1462 Py_ssize_t end;
1463
1464 if (CheckBuffer((BufferObject *)(self)))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001465 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001466
1467 if (!PyArg_ParseTuple(args, "nn", &start, &end))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001468 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001469
1470 return RangeNew(((BufferObject *)(self))->buf, start, end);
1471}
1472
1473/* Line range object - Definitions
1474 */
1475
1476static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001477 /* name, function, calling, documentation */
1478 {"append", RangeAppend, 1, "Append data to the Vim range" },
1479 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001480};
1481
1482static PySequenceMethods RangeAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001483 (lenfunc) RangeLength, /* sq_length, len(x) */
1484 (binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
1485 (ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
1486 (ssizeargfunc) RangeItem, /* sq_item, x[i] */
1487 0, /* was_sq_slice, x[i:j] */
1488 (ssizeobjargproc) RangeAsItem, /* sq_as_item, x[i]=v */
1489 0, /* sq_ass_slice, x[i:j]=v */
1490 0, /* sq_contains */
1491 0, /* sq_inplace_concat */
1492 0, /* sq_inplace_repeat */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001493};
1494
1495PyMappingMethods RangeAsMapping = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001496 /* mp_length */ (lenfunc)RangeLength,
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001497 /* mp_subscript */ (binaryfunc)RangeSubscript,
1498 /* mp_ass_subscript */ (objobjargproc)0,
1499};
1500
1501static PyTypeObject RangeType;
1502
1503/* Line range object - Implementation
1504 */
1505
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001506 static PyObject *
1507RangeNew(buf_T *buf, Py_ssize_t start, Py_ssize_t end)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001508{
1509 BufferObject *bufr;
1510 RangeObject *self;
1511 self = PyObject_NEW(RangeObject, &RangeType);
1512 if (self == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001513 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001514
1515 bufr = (BufferObject *)BufferNew(buf);
1516 if (bufr == NULL)
1517 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001518 Py_DECREF(self);
1519 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001520 }
1521 Py_INCREF(bufr);
1522
1523 self->buf = bufr;
1524 self->start = start;
1525 self->end = end;
1526
1527 return (PyObject *)(self);
1528}
1529
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001530 static void
1531RangeDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001532{
1533 Py_DECREF(((RangeObject *)(self))->buf);
1534}
1535
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001536 static PyObject *
1537RangeGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001538{
1539 char *name = "";
1540 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001541 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001542
1543 if (strcmp(name, "start") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001544 return Py_BuildValue("n", ((RangeObject *)(self))->start - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001545 else if (strcmp(name, "end") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001546 return Py_BuildValue("n", ((RangeObject *)(self))->end - 1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001547 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001548 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001549}
1550
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001551 static PyObject *
1552RangeRepr(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001553{
1554 static char repr[100];
1555 RangeObject *this = (RangeObject *)(self);
1556
1557 if (this->buf->buf == INVALID_BUFFER_VALUE)
1558 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001559 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1560 (self));
1561 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001562 }
1563 else
1564 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001565 char *name = (char *)this->buf->buf->b_fname;
1566 int len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001567
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001568 if (name == NULL)
1569 name = "";
1570 len = (int)strlen(name);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001571
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001572 if (len > 45)
1573 name = name + (45 - len);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001574
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001575 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1576 len > 45 ? "..." : "", name,
1577 this->start, this->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001578
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001579 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001580 }
1581}
1582
1583/****************/
1584
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001585 static Py_ssize_t
1586RangeLength(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001587{
1588 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1589 if (CheckBuffer(((RangeObject *)(self))->buf))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001590 return -1; /* ??? */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001591
1592 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1593}
1594
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001595 static PyObject *
1596RangeItem(PyObject *self, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001597{
1598 return RBItem(((RangeObject *)(self))->buf, n,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001599 ((RangeObject *)(self))->start,
1600 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001601}
1602
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001603 static Py_ssize_t
1604RangeAsItem(PyObject *self, Py_ssize_t n, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001605{
1606 return RBAsItem(((RangeObject *)(self))->buf, n, val,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001607 ((RangeObject *)(self))->start,
1608 ((RangeObject *)(self))->end,
1609 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001610}
1611
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001612 static PyObject *
1613RangeSlice(PyObject *self, Py_ssize_t lo, Py_ssize_t hi)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001614{
1615 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001616 ((RangeObject *)(self))->start,
1617 ((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001618}
1619
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001620 static PyObject *
1621RangeSubscript(PyObject *self, PyObject* idx)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001622{
1623 if (PyLong_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001624 long _idx = PyLong_AsLong(idx);
1625 return RangeItem(self,_idx);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001626 } else if (PySlice_Check(idx)) {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001627 Py_ssize_t start, stop, step, slicelen;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001628
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001629 if (PySlice_GetIndicesEx((PySliceObject *)idx,
1630 ((RangeObject *)(self))->end-((RangeObject *)(self))->start+1,
1631 &start, &stop,
1632 &step, &slicelen) < 0) {
1633 return NULL;
1634 }
1635 return RangeSlice(self,start,stop+1);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001636 } else {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001637 PyErr_SetString(PyExc_IndexError, "Index must be int or slice");
1638 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001639 }
1640}
1641
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001642 static PyObject *
1643RangeAppend(PyObject *self, PyObject *args)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001644{
1645 return RBAppend(((RangeObject *)(self))->buf, args,
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001646 ((RangeObject *)(self))->start,
1647 ((RangeObject *)(self))->end,
1648 &((RangeObject *)(self))->end);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001649}
1650
1651/* Buffer list object - Definitions
1652 */
1653
1654typedef struct
1655{
1656 PyObject_HEAD
1657}
1658BufListObject;
1659
1660static PySequenceMethods BufListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001661 (lenfunc) BufListLength, /* sq_length, len(x) */
1662 (binaryfunc) 0, /* sq_concat, x+y */
1663 (ssizeargfunc) 0, /* sq_repeat, x*n */
1664 (ssizeargfunc) BufListItem, /* sq_item, x[i] */
1665 0, /* was_sq_slice, x[i:j] */
1666 (ssizeobjargproc) 0, /* sq_as_item, x[i]=v */
1667 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001668 0, /* sq_contains */
1669 0, /* sq_inplace_concat */
1670 0, /* sq_inplace_repeat */
1671};
1672
1673static PyTypeObject BufListType;
1674
1675/* Buffer list object - Implementation
1676 */
1677
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001678 static Py_ssize_t
1679BufListLength(PyObject *self UNUSED)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001680{
1681 buf_T *b = firstbuf;
1682 Py_ssize_t n = 0;
1683
1684 while (b)
1685 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001686 ++n;
1687 b = b->b_next;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001688 }
1689
1690 return n;
1691}
1692
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001693 static PyObject *
1694BufListItem(PyObject *self UNUSED, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001695{
1696 buf_T *b;
1697
1698 for (b = firstbuf; b; b = b->b_next, --n)
1699 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001700 if (n == 0)
1701 return BufferNew(b);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001702 }
1703
1704 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1705 return NULL;
1706}
1707
1708/* Window object - Definitions
1709 */
1710
1711static struct PyMethodDef WindowMethods[] = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001712 /* name, function, calling, documentation */
1713 { NULL, NULL, 0, NULL }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001714};
1715
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001716static PyTypeObject WindowType;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001717
1718/* Window object - Implementation
1719 */
1720
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001721 static PyObject *
1722WindowNew(win_T *win)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001723{
1724 /* We need to handle deletion of windows underneath us.
1725 * If we add a "w_python3_ref" field to the win_T structure,
1726 * then we can get at it in win_free() in vim. We then
1727 * need to create only ONE Python object per window - if
1728 * we try to create a second, just INCREF the existing one
1729 * and return it. The (single) Python object referring to
1730 * the window is stored in "w_python3_ref".
1731 * On a win_free() we set the Python object's win_T* field
1732 * to an invalid value. We trap all uses of a window
1733 * object, and reject them if the win_T* field is invalid.
1734 */
1735
1736 WindowObject *self;
1737
1738 if (win->w_python3_ref)
1739 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001740 self = win->w_python3_ref;
1741 Py_INCREF(self);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001742 }
1743 else
1744 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001745 self = PyObject_NEW(WindowObject, &WindowType);
1746 if (self == NULL)
1747 return NULL;
1748 self->win = win;
1749 win->w_python3_ref = self;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001750 }
1751
1752 return (PyObject *)(self);
1753}
1754
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001755 static void
1756WindowDestructor(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001757{
1758 WindowObject *this = (WindowObject *)(self);
1759
1760 if (this->win && this->win != INVALID_WINDOW_VALUE)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001761 this->win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001762}
1763
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001764 static int
1765CheckWindow(WindowObject *this)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001766{
1767 if (this->win == INVALID_WINDOW_VALUE)
1768 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001769 PyErr_SetVim(_("attempt to refer to deleted window"));
1770 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001771 }
1772
1773 return 0;
1774}
1775
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001776 static PyObject *
1777WindowGetattro(PyObject *self, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001778{
1779 WindowObject *this = (WindowObject *)(self);
1780
1781 char *name = "";
1782 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001783 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001784
1785
1786 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001787 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001788
1789 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001790 return (PyObject *)BufferNew(this->win->w_buffer);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001791 else if (strcmp(name, "cursor") == 0)
1792 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001793 pos_T *pos = &this->win->w_cursor;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001794
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001795 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001796 }
1797 else if (strcmp(name, "height") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001798 return Py_BuildValue("l", (long)(this->win->w_height));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001799#ifdef FEAT_VERTSPLIT
1800 else if (strcmp(name, "width") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001801 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001802#endif
1803 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001804 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001805 else
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001806 return PyObject_GenericGetAttr(self, nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001807}
1808
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001809 static int
1810WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001811{
1812 WindowObject *this = (WindowObject *)(self);
1813
1814 char *name = "";
1815 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001816 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001817
1818
1819 if (CheckWindow(this))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001820 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001821
1822 if (strcmp(name, "buffer") == 0)
1823 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001824 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1825 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001826 }
1827 else if (strcmp(name, "cursor") == 0)
1828 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001829 long lnum;
1830 long col;
Bram Moolenaard68554d2010-07-25 13:43:20 +02001831 long len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001832
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001833 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1834 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001835
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001836 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1837 {
1838 PyErr_SetVim(_("cursor position outside buffer"));
1839 return -1;
1840 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001841
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001842 /* Check for keyboard interrupts */
1843 if (VimErrorCheck())
1844 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001845
Bram Moolenaard68554d2010-07-25 13:43:20 +02001846 /* When column is out of range silently correct it. */
1847 len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE));
1848 if (col > len)
1849 col = len;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001850
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001851 this->win->w_cursor.lnum = lnum;
1852 this->win->w_cursor.col = col;
Bram Moolenaard68554d2010-07-25 13:43:20 +02001853#ifdef FEAT_VIRTUALEDIT
1854 this->win->w_cursor.coladd = 0;
1855#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001856 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001857
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001858 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001859 }
1860 else if (strcmp(name, "height") == 0)
1861 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001862 int height;
1863 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001864
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001865 if (!PyArg_Parse(val, "i", &height))
1866 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001867
1868#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001869 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001870#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001871 savewin = curwin;
1872 curwin = this->win;
1873 win_setheight(height);
1874 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001875
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001876 /* Check for keyboard interrupts */
1877 if (VimErrorCheck())
1878 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001879
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001880 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001881 }
1882#ifdef FEAT_VERTSPLIT
1883 else if (strcmp(name, "width") == 0)
1884 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001885 int width;
1886 win_T *savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001887
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001888 if (!PyArg_Parse(val, "i", &width))
1889 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001890
1891#ifdef FEAT_GUI
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001892 need_mouse_correct = TRUE;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001893#endif
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001894 savewin = curwin;
1895 curwin = this->win;
1896 win_setwidth(width);
1897 curwin = savewin;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001898
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001899 /* Check for keyboard interrupts */
1900 if (VimErrorCheck())
1901 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001902
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001903 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001904 }
1905#endif
1906 else
1907 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001908 PyErr_SetString(PyExc_AttributeError, name);
1909 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001910 }
1911}
1912
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001913 static PyObject *
1914WindowRepr(PyObject *self)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001915{
1916 static char repr[100];
1917 WindowObject *this = (WindowObject *)(self);
1918
1919 if (this->win == INVALID_WINDOW_VALUE)
1920 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001921 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
1922 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001923 }
1924 else
1925 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001926 int i = 0;
1927 win_T *w;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001928
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001929 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
1930 ++i;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001931
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001932 if (w == NULL)
1933 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
1934 (self));
1935 else
1936 vim_snprintf(repr, 100, _("<window %d>"), i);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001937
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001938 return PyUnicode_FromString(repr);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001939 }
1940}
1941
1942/* Window list object - Definitions
1943 */
1944
1945typedef struct
1946{
1947 PyObject_HEAD
1948}
1949WinListObject;
1950
1951static PySequenceMethods WinListAsSeq = {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001952 (lenfunc) WinListLength, /* sq_length, len(x) */
1953 (binaryfunc) 0, /* sq_concat, x+y */
1954 (ssizeargfunc) 0, /* sq_repeat, x*n */
1955 (ssizeargfunc) WinListItem, /* sq_item, x[i] */
1956 0, /* sq_slice, x[i:j] */
1957 (ssizeobjargproc)0, /* sq_as_item, x[i]=v */
1958 0, /* sq_ass_slice, x[i:j]=v */
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001959 0, /* sq_contains */
1960 0, /* sq_inplace_concat */
1961 0, /* sq_inplace_repeat */
1962};
1963
1964static PyTypeObject WinListType;
1965
1966/* Window list object - Implementation
1967 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001968 static Py_ssize_t
1969WinListLength(PyObject *self UNUSED)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001970{
1971 win_T *w = firstwin;
1972 Py_ssize_t n = 0;
1973
1974 while (w != NULL)
1975 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001976 ++n;
1977 w = W_NEXT(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001978 }
1979
1980 return n;
1981}
1982
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001983 static PyObject *
1984WinListItem(PyObject *self UNUSED, Py_ssize_t n)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001985{
1986 win_T *w;
1987
1988 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02001989 if (n == 0)
1990 return WindowNew(w);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02001991
1992 PyErr_SetString(PyExc_IndexError, _("no such window"));
1993 return NULL;
1994}
1995
1996/* Current items object - Definitions
1997 */
1998
1999typedef struct
2000{
2001 PyObject_HEAD
2002}
2003CurrentObject;
2004
2005static PyTypeObject CurrentType;
2006
2007/* Current items object - Implementation
2008 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002009 static PyObject *
2010CurrentGetattro(PyObject *self UNUSED, PyObject *nameobj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002011{
2012 char *name = "";
2013 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002014 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002015
2016 if (strcmp(name, "buffer") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002017 return (PyObject *)BufferNew(curbuf);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002018 else if (strcmp(name, "window") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002019 return (PyObject *)WindowNew(curwin);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002020 else if (strcmp(name, "line") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002021 return GetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002022 else if (strcmp(name, "range") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002023 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002024 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002025 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002026 else
2027 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002028 PyErr_SetString(PyExc_AttributeError, name);
2029 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002030 }
2031}
2032
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002033 static int
2034CurrentSetattro(PyObject *self UNUSED, PyObject *nameobj, PyObject *value)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002035{
2036 char *name = "";
2037 if (PyUnicode_Check(nameobj))
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002038 name = _PyUnicode_AsString(nameobj);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002039
2040 if (strcmp(name, "line") == 0)
2041 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002042 if (SetBufferLine(curbuf, (Py_ssize_t)curwin->w_cursor.lnum, value, NULL) == FAIL)
2043 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002044
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002045 return 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002046 }
2047 else
2048 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002049 PyErr_SetString(PyExc_AttributeError, name);
2050 return -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002051 }
2052}
2053
2054/* External interface
2055 */
2056
2057 void
2058python3_buffer_free(buf_T *buf)
2059{
2060 if (buf->b_python3_ref != NULL)
2061 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002062 BufferObject *bp = buf->b_python3_ref;
2063 bp->buf = INVALID_BUFFER_VALUE;
2064 buf->b_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002065 }
2066}
2067
2068#if defined(FEAT_WINDOWS) || defined(PROTO)
2069 void
2070python3_window_free(win_T *win)
2071{
2072 if (win->w_python3_ref != NULL)
2073 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002074 WindowObject *wp = win->w_python3_ref;
2075 wp->win = INVALID_WINDOW_VALUE;
2076 win->w_python3_ref = NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002077 }
2078}
2079#endif
2080
2081static BufListObject TheBufferList =
2082{
2083 PyObject_HEAD_INIT(&BufListType)
2084};
2085
2086static WinListObject TheWindowList =
2087{
2088 PyObject_HEAD_INIT(&WinListType)
2089};
2090
2091static CurrentObject TheCurrent =
2092{
2093 PyObject_HEAD_INIT(&CurrentType)
2094};
2095
2096PyDoc_STRVAR(vim_module_doc,"vim python interface\n");
2097
2098static struct PyModuleDef vimmodule;
2099
Bram Moolenaar69154f22010-07-18 21:42:34 +02002100#ifndef PROTO
2101PyMODINIT_FUNC Py3Init_vim(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002102{
2103 PyObject *mod;
2104 /* The special value is removed from sys.path in Python3_Init(). */
2105 static wchar_t *(argv[2]) = {L"/must>not&exist/foo", NULL};
2106
2107 PyType_Ready(&BufferType);
2108 PyType_Ready(&RangeType);
2109 PyType_Ready(&WindowType);
2110 PyType_Ready(&BufListType);
2111 PyType_Ready(&WinListType);
2112 PyType_Ready(&CurrentType);
2113
2114 /* Set sys.argv[] to avoid a crash in warn(). */
2115 PySys_SetArgv(1, argv);
2116
2117 mod = PyModule_Create(&vimmodule);
2118
2119 VimError = Py_BuildValue("s", "vim.error");
2120
2121 PyModule_AddObject(mod, "error", VimError);
2122 Py_INCREF((PyObject *)(void *)&TheBufferList);
2123 PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
2124 Py_INCREF((PyObject *)(void *)&TheCurrent);
2125 PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
2126 Py_INCREF((PyObject *)(void *)&TheWindowList);
2127 PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
2128
2129 if (PyErr_Occurred())
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002130 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002131
2132 return mod;
2133}
Bram Moolenaar69154f22010-07-18 21:42:34 +02002134#endif
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002135
2136/*************************************************************************
2137 * 4. Utility functions for handling the interface between Vim and Python.
2138 */
2139
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002140/* Get a line from the specified buffer. The line number is
2141 * in Vim format (1-based). The line is returned as a Python
2142 * string object.
2143 */
2144 static PyObject *
2145GetBufferLine(buf_T *buf, Py_ssize_t n)
2146{
2147 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2148}
2149
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002150
2151/* Get a list of lines from the specified buffer. The line numbers
2152 * are in Vim format (1-based). The range is from lo up to, but not
2153 * including, hi. The list is returned as a Python list of string objects.
2154 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002155 static PyObject *
2156GetBufferLineList(buf_T *buf, Py_ssize_t lo, Py_ssize_t hi)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002157{
2158 Py_ssize_t i;
2159 Py_ssize_t n = hi - lo;
2160 PyObject *list = PyList_New(n);
2161
2162 if (list == NULL)
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002163 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002164
2165 for (i = 0; i < n; ++i)
2166 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002167 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002168
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002169 /* Error check - was the Python string creation OK? */
2170 if (str == NULL)
2171 {
2172 Py_DECREF(list);
2173 return NULL;
2174 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002175
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002176 /* Set the list item */
2177 if (PyList_SetItem(list, i, str))
2178 {
2179 Py_DECREF(str);
2180 Py_DECREF(list);
2181 return NULL;
2182 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002183 }
2184
2185 /* The ownership of the Python list is passed to the caller (ie,
2186 * the caller should Py_DECREF() the object when it is finished
2187 * with it).
2188 */
2189
2190 return list;
2191}
2192
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002193/*
2194 * Check if deleting lines made the cursor position invalid.
2195 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2196 * deleted).
2197 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002198 static void
2199py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002200{
2201 if (curwin->w_cursor.lnum >= lo)
2202 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002203 /* Adjust the cursor position if it's in/after the changed
2204 * lines. */
2205 if (curwin->w_cursor.lnum >= hi)
2206 {
2207 curwin->w_cursor.lnum += extra;
2208 check_cursor_col();
2209 }
2210 else if (extra < 0)
2211 {
2212 curwin->w_cursor.lnum = lo;
2213 check_cursor();
2214 }
2215 else
2216 check_cursor_col();
2217 changed_cline_bef_curs();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002218 }
2219 invalidate_botline();
2220}
2221
2222/* Replace a line in the specified buffer. The line number is
2223 * in Vim format (1-based). The replacement line is given as
2224 * a Python string object. The object is checked for validity
2225 * and correct format. Errors are returned as a value of FAIL.
2226 * The return value is OK on success.
2227 * If OK is returned and len_change is not NULL, *len_change
2228 * is set to the change in the buffer length.
2229 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002230 static int
2231SetBufferLine(buf_T *buf, Py_ssize_t n, PyObject *line, Py_ssize_t *len_change)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002232{
2233 /* First of all, we check the thpe of the supplied Python object.
2234 * There are three cases:
2235 * 1. NULL, or None - this is a deletion.
2236 * 2. A string - this is a replacement.
2237 * 3. Anything else - this is an error.
2238 */
2239 if (line == Py_None || line == NULL)
2240 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002241 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002242
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002243 PyErr_Clear();
2244 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002245
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002246 if (u_savedel((linenr_T)n, 1L) == FAIL)
2247 PyErr_SetVim(_("cannot save undo information"));
2248 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2249 PyErr_SetVim(_("cannot delete line"));
2250 else
2251 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002252 if (buf == curwin->w_buffer)
2253 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
Bram Moolenaard68554d2010-07-25 13:43:20 +02002254 deleted_lines_mark((linenr_T)n, 1L);
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002255 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002256
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002257 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002258
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002259 if (PyErr_Occurred() || VimErrorCheck())
2260 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002261
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002262 if (len_change)
2263 *len_change = -1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002264
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002265 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002266 }
2267 else if (PyUnicode_Check(line))
2268 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002269 char *save = StringToLine(line);
2270 buf_T *savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002271
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002272 if (save == NULL)
2273 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002274
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002275 /* We do not need to free "save" if ml_replace() consumes it. */
2276 PyErr_Clear();
2277 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002278
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002279 if (u_savesub((linenr_T)n) == FAIL)
2280 {
2281 PyErr_SetVim(_("cannot save undo information"));
2282 vim_free(save);
2283 }
2284 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2285 {
2286 PyErr_SetVim(_("cannot replace line"));
2287 vim_free(save);
2288 }
2289 else
2290 changed_bytes((linenr_T)n, 0);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002291
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002292 curbuf = savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002293
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002294 /* Check that the cursor is not beyond the end of the line now. */
2295 if (buf == curwin->w_buffer)
2296 check_cursor_col();
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002297
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002298 if (PyErr_Occurred() || VimErrorCheck())
2299 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002300
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002301 if (len_change)
2302 *len_change = 0;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002303
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002304 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002305 }
2306 else
2307 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002308 PyErr_BadArgument();
2309 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002310 }
2311}
2312
2313/* Insert a number of lines into the specified buffer after the specifed line.
2314 * The line number is in Vim format (1-based). The lines to be inserted are
2315 * given as a Python list of string objects or as a single string. The lines
2316 * to be added are checked for validity and correct format. Errors are
2317 * returned as a value of FAIL. The return value is OK on success.
2318 * If OK is returned and len_change is not NULL, *len_change
2319 * is set to the change in the buffer length.
2320 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002321 static int
2322InsertBufferLines(buf_T *buf, Py_ssize_t n, PyObject *lines, Py_ssize_t *len_change)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002323{
2324 /* First of all, we check the type of the supplied Python object.
2325 * It must be a string or a list, or the call is in error.
2326 */
2327 if (PyUnicode_Check(lines))
2328 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002329 char *str = StringToLine(lines);
2330 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002331
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002332 if (str == NULL)
2333 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002334
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002335 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002336
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002337 PyErr_Clear();
2338 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002339
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002340 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2341 PyErr_SetVim(_("cannot save undo information"));
2342 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2343 PyErr_SetVim(_("cannot insert line"));
2344 else
2345 appended_lines_mark((linenr_T)n, 1L);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002346
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002347 vim_free(str);
2348 curbuf = savebuf;
2349 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002350
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002351 if (PyErr_Occurred() || VimErrorCheck())
2352 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002353
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002354 if (len_change)
2355 *len_change = 1;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002356
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002357 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002358 }
2359 else if (PyList_Check(lines))
2360 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002361 Py_ssize_t i;
2362 Py_ssize_t size = PyList_Size(lines);
2363 char **array;
2364 buf_T *savebuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002365
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002366 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2367 if (array == NULL)
2368 {
2369 PyErr_NoMemory();
2370 return FAIL;
2371 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002372
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002373 for (i = 0; i < size; ++i)
2374 {
2375 PyObject *line = PyList_GetItem(lines, i);
2376 array[i] = StringToLine(line);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002377
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002378 if (array[i] == NULL)
2379 {
2380 while (i)
2381 vim_free(array[--i]);
2382 vim_free(array);
2383 return FAIL;
2384 }
2385 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002386
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002387 savebuf = curbuf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002388
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002389 PyErr_Clear();
2390 curbuf = buf;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002391
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002392 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2393 PyErr_SetVim(_("cannot save undo information"));
2394 else
2395 {
2396 for (i = 0; i < size; ++i)
2397 {
2398 if (ml_append((linenr_T)(n + i),
2399 (char_u *)array[i], 0, FALSE) == FAIL)
2400 {
2401 PyErr_SetVim(_("cannot insert line"));
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002402
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002403 /* Free the rest of the lines */
2404 while (i < size)
2405 vim_free(array[i++]);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002406
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002407 break;
2408 }
2409 vim_free(array[i]);
2410 }
2411 if (i > 0)
2412 appended_lines_mark((linenr_T)n, (long)i);
2413 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002414
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002415 /* Free the array of lines. All of its contents have now
2416 * been freed.
2417 */
2418 vim_free(array);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002419
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002420 curbuf = savebuf;
2421 update_screen(VALID);
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002422
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002423 if (PyErr_Occurred() || VimErrorCheck())
2424 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002425
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002426 if (len_change)
2427 *len_change = size;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002428
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002429 return OK;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002430 }
2431 else
2432 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002433 PyErr_BadArgument();
2434 return FAIL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002435 }
2436}
2437
2438/* Convert a Vim line into a Python string.
2439 * All internal newlines are replaced by null characters.
2440 *
2441 * On errors, the Python exception data is set, and NULL is returned.
2442 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002443 static PyObject *
2444LineToString(const char *str)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002445{
2446 PyObject *result;
2447 Py_ssize_t len = strlen(str);
2448 char *tmp,*p;
2449
2450 tmp = (char *)alloc((unsigned)(len+1));
2451 p = tmp;
2452 if (p == NULL)
2453 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002454 PyErr_NoMemory();
2455 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002456 }
2457
2458 while (*str)
2459 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002460 if (*str == '\n')
2461 *p = '\0';
2462 else
2463 *p = *str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002464
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002465 ++p;
2466 ++str;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002467 }
2468 *p = '\0';
2469
2470 result = PyUnicode_FromStringAndSize(tmp, len);
2471
2472 vim_free(tmp);
2473 return result;
2474}
2475
2476/* Convert a Python string into a Vim line.
2477 *
2478 * The result is in allocated memory. All internal nulls are replaced by
2479 * newline characters. It is an error for the string to contain newline
2480 * characters.
2481 *
2482 * On errors, the Python exception data is set, and NULL is returned.
2483 */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002484 static char *
2485StringToLine(PyObject *obj)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002486{
2487 const char *str;
2488 char *save;
2489 Py_ssize_t len;
2490 Py_ssize_t i;
2491 char *p;
2492
2493 if (obj == NULL || !PyUnicode_Check(obj))
2494 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002495 PyErr_BadArgument();
2496 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002497 }
2498
2499 str = _PyUnicode_AsString(obj);
2500 len = PyUnicode_GET_SIZE(obj);
2501
2502 /*
2503 * Error checking: String must not contain newlines, as we
2504 * are replacing a single line, and we must replace it with
2505 * a single line.
2506 * A trailing newline is removed, so that append(f.readlines()) works.
2507 */
2508 p = memchr(str, '\n', len);
2509 if (p != NULL)
2510 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002511 if (p == str + len - 1)
2512 --len;
2513 else
2514 {
2515 PyErr_SetVim(_("string cannot contain newlines"));
2516 return NULL;
2517 }
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002518 }
2519
2520 /* Create a copy of the string, with internal nulls replaced by
2521 * newline characters, as is the vim convention.
2522 */
2523 save = (char *)alloc((unsigned)(len+1));
2524 if (save == NULL)
2525 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002526 PyErr_NoMemory();
2527 return NULL;
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002528 }
2529
2530 for (i = 0; i < len; ++i)
2531 {
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002532 if (str[i] == '\0')
2533 save[i] = '\n';
2534 else
2535 save[i] = str[i];
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002536 }
2537
2538 save[i] = '\0';
2539
2540 return save;
2541}
2542
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002543 static void
2544init_structs(void)
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002545{
2546 vim_memset(&OutputType, 0, sizeof(OutputType));
2547 OutputType.tp_name = "vim.message";
2548 OutputType.tp_basicsize = sizeof(OutputObject);
2549 OutputType.tp_getattro = OutputGetattro;
2550 OutputType.tp_setattro = OutputSetattro;
2551 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
2552 OutputType.tp_doc = "vim message object";
2553 OutputType.tp_methods = OutputMethods;
2554 OutputType.tp_alloc = call_PyType_GenericAlloc;
2555 OutputType.tp_new = call_PyType_GenericNew;
2556 OutputType.tp_free = call_PyObject_Free;
2557
2558 vim_memset(&BufferType, 0, sizeof(BufferType));
2559 BufferType.tp_name = "vim.buffer";
2560 BufferType.tp_basicsize = sizeof(BufferType);
2561 BufferType.tp_dealloc = BufferDestructor;
2562 BufferType.tp_repr = BufferRepr;
2563 BufferType.tp_as_sequence = &BufferAsSeq;
2564 BufferType.tp_as_mapping = &BufferAsMapping;
2565 BufferType.tp_getattro = BufferGetattro;
2566 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
2567 BufferType.tp_doc = "vim buffer object";
2568 BufferType.tp_methods = BufferMethods;
2569 BufferType.tp_alloc = call_PyType_GenericAlloc;
2570 BufferType.tp_new = call_PyType_GenericNew;
2571 BufferType.tp_free = call_PyObject_Free;
2572
Bram Moolenaar55d5c032010-07-17 23:52:29 +02002573 vim_memset(&WindowType, 0, sizeof(WindowType));
2574 WindowType.tp_name = "vim.window";
2575 WindowType.tp_basicsize = sizeof(WindowObject);
2576 WindowType.tp_dealloc = WindowDestructor;
2577 WindowType.tp_repr = WindowRepr;
2578 WindowType.tp_getattro = WindowGetattro;
2579 WindowType.tp_setattro = WindowSetattro;
2580 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
2581 WindowType.tp_doc = "vim Window object";
2582 WindowType.tp_methods = WindowMethods;
2583 WindowType.tp_alloc = call_PyType_GenericAlloc;
2584 WindowType.tp_new = call_PyType_GenericNew;
2585 WindowType.tp_free = call_PyObject_Free;
2586
Bram Moolenaarbd5e15f2010-07-17 21:19:38 +02002587 vim_memset(&BufListType, 0, sizeof(BufListType));
2588 BufListType.tp_name = "vim.bufferlist";
2589 BufListType.tp_basicsize = sizeof(BufListObject);
2590 BufListType.tp_as_sequence = &BufListAsSeq;
2591 BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
2592 BufferType.tp_doc = "vim buffer list";
2593
2594 vim_memset(&WinListType, 0, sizeof(WinListType));
2595 WinListType.tp_name = "vim.windowlist";
2596 WinListType.tp_basicsize = sizeof(WinListType);
2597 WinListType.tp_as_sequence = &WinListAsSeq;
2598 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
2599 WinListType.tp_doc = "vim window list";
2600
2601 vim_memset(&RangeType, 0, sizeof(RangeType));
2602 RangeType.tp_name = "vim.range";
2603 RangeType.tp_basicsize = sizeof(RangeObject);
2604 RangeType.tp_dealloc = RangeDestructor;
2605 RangeType.tp_repr = RangeRepr;
2606 RangeType.tp_as_sequence = &RangeAsSeq;
2607 RangeType.tp_as_mapping = &RangeAsMapping;
2608 RangeType.tp_getattro = RangeGetattro;
2609 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
2610 RangeType.tp_doc = "vim Range object";
2611 RangeType.tp_methods = RangeMethods;
2612 RangeType.tp_alloc = call_PyType_GenericAlloc;
2613 RangeType.tp_new = call_PyType_GenericNew;
2614 RangeType.tp_free = call_PyObject_Free;
2615
2616 vim_memset(&CurrentType, 0, sizeof(CurrentType));
2617 CurrentType.tp_name = "vim.currentdata";
2618 CurrentType.tp_basicsize = sizeof(CurrentObject);
2619 CurrentType.tp_getattro = CurrentGetattro;
2620 CurrentType.tp_setattro = CurrentSetattro;
2621 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
2622 CurrentType.tp_doc = "vim current object";
2623
2624 vim_memset(&vimmodule, 0, sizeof(vimmodule));
2625 vimmodule.m_name = "vim";
2626 vimmodule.m_doc = vim_module_doc;
2627 vimmodule.m_size = -1;
2628 vimmodule.m_methods = VimMethods;
2629}