blob: 088bc5e744d9b6fd4e2e455800fc0aee8ac76b6c [file] [log] [blame]
Bram Moolenaardb913952012-06-29 12:54:53 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002 *
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/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020010 * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
11 * Pavlov.
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020012 *
13 * Common code for if_python.c and if_python3.c.
14 */
15
Bram Moolenaarc1a995d2012-08-08 16:05:07 +020016#if PY_VERSION_HEX < 0x02050000
17typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
18#endif
19
Bram Moolenaar91805fc2011-06-26 04:01:44 +020020#ifdef FEAT_MBYTE
21# define ENC_OPT p_enc
22#else
23# define ENC_OPT "latin1"
24#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020025#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020026
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020027#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
28
29#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
30#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020031#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020032
Bram Moolenaare9ba5162013-05-29 22:02:22 +020033#define DICTKEY_DECL \
34 PyObject *dictkey_todecref;
Bram Moolenaara03e6312013-05-29 22:49:26 +020035#define DICTKEY_GET(err, decref) \
Bram Moolenaare9ba5162013-05-29 22:02:22 +020036 if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
Bram Moolenaara03e6312013-05-29 22:49:26 +020037 { \
38 if (decref) \
39 { \
40 Py_DECREF(keyObject); \
41 } \
Bram Moolenaarc37b6ec2013-05-29 22:43:37 +020042 return err; \
Bram Moolenaara03e6312013-05-29 22:49:26 +020043 } \
44 if (decref && !dictkey_todecref) \
45 dictkey_todecref = keyObject; \
Bram Moolenaarc37b6ec2013-05-29 22:43:37 +020046 if (*key == NUL) \
47 { \
48 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
49 return err; \
50 }
Bram Moolenaare9ba5162013-05-29 22:02:22 +020051#define DICTKEY_UNREF \
52 Py_XDECREF(dictkey_todecref);
53
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020054typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020055typedef void (*runner)(const char *, void *
56#ifdef PY_CAN_RECURSE
57 , PyGILState_STATE *
58#endif
59 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020060
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020061static int ConvertFromPyObject(PyObject *, typval_T *);
62static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020063static PyObject *WindowNew(win_T *, tabpage_T *);
64static PyObject *BufferNew (buf_T *);
65static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020066
67static PyInt RangeStart;
68static PyInt RangeEnd;
69
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020070static PyObject *globals;
71
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020072/*
73 * obtain a lock on the Vim data structures
74 */
75 static void
76Python_Lock_Vim(void)
77{
78}
79
80/*
81 * release a lock on the Vim data structures
82 */
83 static void
84Python_Release_Vim(void)
85{
86}
87
Bram Moolenaare9ba5162013-05-29 22:02:22 +020088/*
89 * The "todecref" argument holds a pointer to PyObject * that must be
90 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
91 * was needed to generate returned value is object.
92 *
93 * Use Py_XDECREF to decrement reference count.
94 */
95 static char_u *
96StringToChars(PyObject *object, PyObject **todecref)
97{
98 char_u *p;
99 PyObject *bytes = NULL;
100
101 if (PyBytes_Check(object))
102 {
103
104 if (PyString_AsStringAndSize(object, (char **) &p, NULL) == -1)
105 return NULL;
106 if (p == NULL)
107 return NULL;
108
109 *todecref = NULL;
110 }
111 else if (PyUnicode_Check(object))
112 {
113 bytes = PyUnicode_AsEncodedString(object, (char *)ENC_OPT, NULL);
114 if (bytes == NULL)
115 return NULL;
116
117 if(PyString_AsStringAndSize(bytes, (char **) &p, NULL) == -1)
118 return NULL;
119 if (p == NULL)
120 return NULL;
121
122 *todecref = bytes;
123 }
124 else
125 {
126 PyErr_SetString(PyExc_TypeError, _("object must be string"));
127 return NULL;
128 }
129
130 return (char_u *) p;
131}
132
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200133 static int
134add_string(PyObject *list, char *s)
135{
136 PyObject *string;
137
138 if (!(string = PyString_FromString(s)))
139 return -1;
140 if (PyList_Append(list, string))
141 {
142 Py_DECREF(string);
143 return -1;
144 }
145
146 Py_DECREF(string);
147 return 0;
148}
149
150 static PyObject *
151ObjectDir(PyObject *self, char **attributes)
152{
153 PyMethodDef *method;
154 char **attr;
155 PyObject *r;
156
157 if (!(r = PyList_New(0)))
158 return NULL;
159
160 if (self)
161 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
162 if (add_string(r, (char *) method->ml_name))
163 {
164 Py_DECREF(r);
165 return NULL;
166 }
167
168 for (attr = attributes ; *attr ; ++attr)
169 if (add_string(r, *attr))
170 {
171 Py_DECREF(r);
172 return NULL;
173 }
174
175#if PY_MAJOR_VERSION < 3
176 if (add_string(r, "__members__"))
177 {
178 Py_DECREF(r);
179 return NULL;
180 }
181#endif
182
183 return r;
184}
185
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200186/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200187 */
188
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200189/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200190typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200191
192static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200193
194typedef struct
195{
196 PyObject_HEAD
197 long softspace;
198 long error;
199} OutputObject;
200
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200201static char *OutputAttrs[] = {
202 "softspace",
203 NULL
204};
205
206 static PyObject *
207OutputDir(PyObject *self)
208{
209 return ObjectDir(self, OutputAttrs);
210}
211
Bram Moolenaar77045652012-09-21 13:46:06 +0200212 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200213OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +0200214{
215 if (val == NULL)
216 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200217 PyErr_SetString(PyExc_AttributeError,
218 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200219 return -1;
220 }
221
222 if (strcmp(name, "softspace") == 0)
223 {
224 if (!PyInt_Check(val))
225 {
226 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
227 return -1;
228 }
229
Bram Moolenaard6e39182013-05-21 18:30:34 +0200230 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +0200231 return 0;
232 }
233
234 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
235 return -1;
236}
237
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200238/* Buffer IO, we write one whole line at a time. */
239static garray_T io_ga = {0, 0, 1, 80, NULL};
240static writefn old_fn = NULL;
241
242 static void
243PythonIO_Flush(void)
244{
245 if (old_fn != NULL && io_ga.ga_len > 0)
246 {
247 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
248 old_fn((char_u *)io_ga.ga_data);
249 }
250 io_ga.ga_len = 0;
251}
252
253 static void
254writer(writefn fn, char_u *str, PyInt n)
255{
256 char_u *ptr;
257
258 /* Flush when switching output function. */
259 if (fn != old_fn)
260 PythonIO_Flush();
261 old_fn = fn;
262
263 /* Write each NL separated line. Text after the last NL is kept for
264 * writing later. */
265 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
266 {
267 PyInt len = ptr - str;
268
269 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
270 break;
271
272 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
273 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
274 fn((char_u *)io_ga.ga_data);
275 str = ptr + 1;
276 n -= len + 1;
277 io_ga.ga_len = 0;
278 }
279
280 /* Put the remaining text into io_ga for later printing. */
281 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
282 {
283 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
284 io_ga.ga_len += (int)n;
285 }
286}
287
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200288 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200289OutputWrite(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200290{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200291 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200292 char *str = NULL;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200293 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200294
Bram Moolenaar27564802011-09-07 19:30:21 +0200295 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200296 return NULL;
297
298 Py_BEGIN_ALLOW_THREADS
299 Python_Lock_Vim();
300 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
301 Python_Release_Vim();
302 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200303 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200304
305 Py_INCREF(Py_None);
306 return Py_None;
307}
308
309 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200310OutputWritelines(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200311{
312 PyInt n;
313 PyInt i;
314 PyObject *list;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200315 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200316
317 if (!PyArg_ParseTuple(args, "O", &list))
318 return NULL;
319 Py_INCREF(list);
320
Bram Moolenaardb913952012-06-29 12:54:53 +0200321 if (!PyList_Check(list))
322 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200323 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
324 Py_DECREF(list);
325 return NULL;
326 }
327
328 n = PyList_Size(list);
329
330 for (i = 0; i < n; ++i)
331 {
332 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200333 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200334 PyInt len;
335
Bram Moolenaardb913952012-06-29 12:54:53 +0200336 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
337 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200338 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
339 Py_DECREF(list);
340 return NULL;
341 }
342
343 Py_BEGIN_ALLOW_THREADS
344 Python_Lock_Vim();
345 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
346 Python_Release_Vim();
347 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200348 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200349 }
350
351 Py_DECREF(list);
352 Py_INCREF(Py_None);
353 return Py_None;
354}
355
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100356 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200357OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100358{
359 /* do nothing */
360 Py_INCREF(Py_None);
361 return Py_None;
362}
363
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200364/***************/
365
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200366static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200367 /* name, function, calling, doc */
368 {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
369 {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
370 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200371 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200372 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200373};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200374
375static OutputObject Output =
376{
377 PyObject_HEAD_INIT(&OutputType)
378 0,
379 0
380};
381
382static OutputObject Error =
383{
384 PyObject_HEAD_INIT(&OutputType)
385 0,
386 1
387};
388
389 static int
390PythonIO_Init_io(void)
391{
392 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
393 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
394
395 if (PyErr_Occurred())
396 {
397 EMSG(_("E264: Python: Error initialising I/O objects"));
398 return -1;
399 }
400
401 return 0;
402}
403
404
405static PyObject *VimError;
406
407/* Check to see whether a Vim error has been reported, or a keyboard
408 * interrupt has been detected.
409 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200410
411 static void
412VimTryStart(void)
413{
414 ++trylevel;
415}
416
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200417 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200418VimTryEnd(void)
419{
420 --trylevel;
421 if (got_int)
422 {
423 PyErr_SetNone(PyExc_KeyboardInterrupt);
424 return 1;
425 }
426 else if (!did_throw)
427 return 0;
428 else if (PyErr_Occurred())
429 return 1;
430 else
431 {
432 PyErr_SetVim((char *) current_exception->value);
433 discard_current_exception();
434 return 1;
435 }
436}
437
438 static int
439VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200440{
441 if (got_int)
442 {
443 PyErr_SetNone(PyExc_KeyboardInterrupt);
444 return 1;
445 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200446 return 0;
447}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200448
449/* Vim module - Implementation
450 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200451
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200452 static PyObject *
453VimCommand(PyObject *self UNUSED, PyObject *args)
454{
455 char *cmd;
456 PyObject *result;
457
458 if (!PyArg_ParseTuple(args, "s", &cmd))
459 return NULL;
460
461 PyErr_Clear();
462
463 Py_BEGIN_ALLOW_THREADS
464 Python_Lock_Vim();
465
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200466 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200467 do_cmdline_cmd((char_u *)cmd);
468 update_screen(VALID);
469
470 Python_Release_Vim();
471 Py_END_ALLOW_THREADS
472
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200473 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200474 result = NULL;
475 else
476 result = Py_None;
477
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200478
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200479 Py_XINCREF(result);
480 return result;
481}
482
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200483/*
484 * Function to translate a typval_T into a PyObject; this will recursively
485 * translate lists/dictionaries into their Python equivalents.
486 *
487 * The depth parameter is to avoid infinite recursion, set it to 1 when
488 * you call VimToPython.
489 */
490 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200491VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200492{
493 PyObject *result;
494 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200495 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200496
497 /* Avoid infinite recursion */
498 if (depth > 100)
499 {
500 Py_INCREF(Py_None);
501 result = Py_None;
502 return result;
503 }
504
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200505 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200506 * then and we can use it again. */
507 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
508 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
509 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200510 sprintf(ptrBuf, "%p",
511 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
512 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200513
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200514 if ((result = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200515 {
516 Py_INCREF(result);
517 return result;
518 }
519 }
520
521 if (our_tv->v_type == VAR_STRING)
522 {
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200523 result = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200524 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200525 }
526 else if (our_tv->v_type == VAR_NUMBER)
527 {
528 char buf[NUMBUFLEN];
529
530 /* For backwards compatibility numbers are stored as strings. */
531 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200532 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200533 }
534# ifdef FEAT_FLOAT
535 else if (our_tv->v_type == VAR_FLOAT)
536 {
537 char buf[NUMBUFLEN];
538
539 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200540 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200541 }
542# endif
543 else if (our_tv->v_type == VAR_LIST)
544 {
545 list_T *list = our_tv->vval.v_list;
546 listitem_T *curr;
547
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200548 if (list == NULL)
549 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200550
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200551 if (!(result = PyList_New(0)))
552 return NULL;
553
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200554 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200555 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200556 Py_DECREF(result);
557 return NULL;
558 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200559
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200560 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
561 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200562 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200563 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200564 Py_DECREF(result);
565 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200566 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200567 if (PyList_Append(result, newObj))
568 {
569 Py_DECREF(newObj);
570 Py_DECREF(result);
571 return NULL;
572 }
573 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200574 }
575 }
576 else if (our_tv->v_type == VAR_DICT)
577 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200578
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200579 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
580 long_u todo = ht->ht_used;
581 hashitem_T *hi;
582 dictitem_T *di;
583 if (our_tv->vval.v_dict == NULL)
584 return NULL;
585
586 if (!(result = PyDict_New()))
587 return NULL;
588
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200589 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200590 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200591 Py_DECREF(result);
592 return NULL;
593 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200594
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200595 for (hi = ht->ht_array; todo > 0; ++hi)
596 {
597 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200598 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200599 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200600
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200601 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200602 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200603 {
604 Py_DECREF(result);
605 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200606 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200607 if (PyDict_SetItemString(result, (char *)hi->hi_key, newObj))
608 {
609 Py_DECREF(result);
610 Py_DECREF(newObj);
611 return NULL;
612 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200613 }
614 }
615 }
616 else
617 {
618 Py_INCREF(Py_None);
619 result = Py_None;
620 }
621
622 return result;
623}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200624
625 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200626VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200627{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200628 char *expr;
629 typval_T *our_tv;
630 PyObject *result;
631 PyObject *lookup_dict;
632
633 if (!PyArg_ParseTuple(args, "s", &expr))
634 return NULL;
635
636 Py_BEGIN_ALLOW_THREADS
637 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200638 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200639 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200640 Python_Release_Vim();
641 Py_END_ALLOW_THREADS
642
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200643 if (VimTryEnd())
644 return NULL;
645
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200646 if (our_tv == NULL)
647 {
648 PyErr_SetVim(_("invalid expression"));
649 return NULL;
650 }
651
652 /* Convert the Vim type into a Python type. Create a dictionary that's
653 * used to check for recursive loops. */
654 lookup_dict = PyDict_New();
655 result = VimToPython(our_tv, 1, lookup_dict);
656 Py_DECREF(lookup_dict);
657
658
659 Py_BEGIN_ALLOW_THREADS
660 Python_Lock_Vim();
661 free_tv(our_tv);
662 Python_Release_Vim();
663 Py_END_ALLOW_THREADS
664
665 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200666}
667
Bram Moolenaardb913952012-06-29 12:54:53 +0200668static PyObject *ConvertToPyObject(typval_T *);
669
670 static PyObject *
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200671VimEvalPy(PyObject *self UNUSED, PyObject *args)
Bram Moolenaardb913952012-06-29 12:54:53 +0200672{
Bram Moolenaardb913952012-06-29 12:54:53 +0200673 char *expr;
674 typval_T *our_tv;
675 PyObject *result;
676
677 if (!PyArg_ParseTuple(args, "s", &expr))
678 return NULL;
679
680 Py_BEGIN_ALLOW_THREADS
681 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200682 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +0200683 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200684 Python_Release_Vim();
685 Py_END_ALLOW_THREADS
686
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200687 if (VimTryEnd())
688 return NULL;
689
Bram Moolenaardb913952012-06-29 12:54:53 +0200690 if (our_tv == NULL)
691 {
692 PyErr_SetVim(_("invalid expression"));
693 return NULL;
694 }
695
696 result = ConvertToPyObject(our_tv);
697 Py_BEGIN_ALLOW_THREADS
698 Python_Lock_Vim();
699 free_tv(our_tv);
700 Python_Release_Vim();
701 Py_END_ALLOW_THREADS
702
703 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200704}
705
706 static PyObject *
707VimStrwidth(PyObject *self UNUSED, PyObject *args)
708{
709 char *expr;
710
711 if (!PyArg_ParseTuple(args, "s", &expr))
712 return NULL;
713
Bram Moolenaara54bf402012-12-05 16:30:07 +0100714 return PyLong_FromLong(
715#ifdef FEAT_MBYTE
716 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
717#else
718 STRLEN(expr)
719#endif
720 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200721}
722
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200723/*
724 * Vim module - Definitions
725 */
726
727static struct PyMethodDef VimMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200728 /* name, function, calling, documentation */
729 {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
730 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
731 {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
732 {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
733 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200734};
735
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200736/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200737 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200738 */
739
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200740static PyTypeObject IterType;
741
742typedef PyObject *(*nextfun)(void **);
743typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200744typedef int (*traversefun)(void *, visitproc, void *);
745typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200746
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200747/* Main purpose of this object is removing the need for do python
748 * initialization (i.e. PyType_Ready and setting type attributes) for a big
749 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200750
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200751typedef struct
752{
753 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200754 void *cur;
755 nextfun next;
756 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200757 traversefun traverse;
758 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200759} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200760
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200761 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200762IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
763 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200764{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200765 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200766
Bram Moolenaar774267b2013-05-21 20:51:59 +0200767 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200768 self->cur = start;
769 self->next = next;
770 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200771 self->traverse = traverse;
772 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200773
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200774 return (PyObject *)(self);
775}
776
777 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200778IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200779{
Bram Moolenaar774267b2013-05-21 20:51:59 +0200780 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +0200781 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +0200782 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200783}
784
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200785 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200786IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200787{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200788 if (self->traverse != NULL)
789 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200790 else
791 return 0;
792}
793
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200794/* Mac OSX defines clear() somewhere. */
795#ifdef clear
796# undef clear
797#endif
798
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200799 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200800IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200801{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200802 if (self->clear != NULL)
803 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200804 else
805 return 0;
806}
807
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200808 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200809IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200810{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200811 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200812}
813
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200814 static PyObject *
815IterIter(PyObject *self)
816{
Bram Moolenaar1bcabe12013-05-29 22:52:32 +0200817 Py_INCREF(self);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200818 return self;
819}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200820
Bram Moolenaardb913952012-06-29 12:54:53 +0200821typedef struct pylinkedlist_S {
822 struct pylinkedlist_S *pll_next;
823 struct pylinkedlist_S *pll_prev;
824 PyObject *pll_obj;
825} pylinkedlist_T;
826
827static pylinkedlist_T *lastdict = NULL;
828static pylinkedlist_T *lastlist = NULL;
829
830 static void
831pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
832{
833 if (ref->pll_prev == NULL)
834 {
835 if (ref->pll_next == NULL)
836 {
837 *last = NULL;
838 return;
839 }
840 }
841 else
842 ref->pll_prev->pll_next = ref->pll_next;
843
844 if (ref->pll_next == NULL)
845 *last = ref->pll_prev;
846 else
847 ref->pll_next->pll_prev = ref->pll_prev;
848}
849
850 static void
851pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
852{
853 if (*last == NULL)
854 ref->pll_prev = NULL;
855 else
856 {
857 (*last)->pll_next = ref;
858 ref->pll_prev = *last;
859 }
860 ref->pll_next = NULL;
861 ref->pll_obj = self;
862 *last = ref;
863}
864
865static PyTypeObject DictionaryType;
866
867typedef struct
868{
869 PyObject_HEAD
870 dict_T *dict;
871 pylinkedlist_T ref;
872} DictionaryObject;
873
874 static PyObject *
875DictionaryNew(dict_T *dict)
876{
877 DictionaryObject *self;
878
879 self = PyObject_NEW(DictionaryObject, &DictionaryType);
880 if (self == NULL)
881 return NULL;
882 self->dict = dict;
883 ++dict->dv_refcount;
884
885 pyll_add((PyObject *)(self), &self->ref, &lastdict);
886
887 return (PyObject *)(self);
888}
889
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200890 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200891DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200892{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200893 pyll_remove(&self->ref, &lastdict);
894 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200895
896 DESTRUCTOR_FINISH(self);
897}
898
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200899static char *DictionaryAttrs[] = {
900 "locked", "scope",
901 NULL
902};
903
904 static PyObject *
905DictionaryDir(PyObject *self)
906{
907 return ObjectDir(self, DictionaryAttrs);
908}
909
Bram Moolenaardb913952012-06-29 12:54:53 +0200910 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200911DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200912{
913 if (val == NULL)
914 {
915 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
916 return -1;
917 }
918
919 if (strcmp(name, "locked") == 0)
920 {
Bram Moolenaard6e39182013-05-21 18:30:34 +0200921 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200922 {
923 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
924 return -1;
925 }
926 else
927 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200928 int istrue = PyObject_IsTrue(val);
929 if (istrue == -1)
930 return -1;
931 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +0200932 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200933 else
Bram Moolenaard6e39182013-05-21 18:30:34 +0200934 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200935 }
936 return 0;
937 }
938 else
939 {
940 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
941 return -1;
942 }
943}
944
945 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200946DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200947{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200948 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +0200949}
950
951 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200952DictionaryItem(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200953{
954 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200955 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200956 DICTKEY_DECL
957
Bram Moolenaara03e6312013-05-29 22:49:26 +0200958 DICTKEY_GET(NULL, 0)
Bram Moolenaardb913952012-06-29 12:54:53 +0200959
Bram Moolenaard6e39182013-05-21 18:30:34 +0200960 di = dict_find(self->dict, key, -1);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200961
Bram Moolenaar696c2112012-09-21 13:43:14 +0200962 DICTKEY_UNREF
963
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200964 if (di == NULL)
965 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200966 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200967 return NULL;
968 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200969
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200970 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200971}
972
973 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200974DictionaryAssItem(DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200975{
976 char_u *key;
977 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200978 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200979 dictitem_T *di;
980 DICTKEY_DECL
981
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200982 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +0200983 {
984 PyErr_SetVim(_("dict is locked"));
985 return -1;
986 }
987
Bram Moolenaara03e6312013-05-29 22:49:26 +0200988 DICTKEY_GET(-1, 0)
Bram Moolenaardb913952012-06-29 12:54:53 +0200989
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200990 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +0200991
992 if (valObject == NULL)
993 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200994 hashitem_T *hi;
995
Bram Moolenaardb913952012-06-29 12:54:53 +0200996 if (di == NULL)
997 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200998 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200999 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +02001000 return -1;
1001 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001002 hi = hash_find(&dict->dv_hashtab, di->di_key);
1003 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +02001004 dictitem_free(di);
1005 return 0;
1006 }
1007
1008 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02001009 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02001010
1011 if (di == NULL)
1012 {
1013 di = dictitem_alloc(key);
1014 if (di == NULL)
1015 {
1016 PyErr_NoMemory();
1017 return -1;
1018 }
1019 di->di_tv.v_lock = 0;
1020
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001021 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001022 {
Bram Moolenaar696c2112012-09-21 13:43:14 +02001023 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +02001024 vim_free(di);
1025 PyErr_SetVim(_("failed to add key to dictionary"));
1026 return -1;
1027 }
1028 }
1029 else
1030 clear_tv(&di->di_tv);
1031
1032 DICTKEY_UNREF
1033
1034 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001035 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001036 return 0;
1037}
1038
1039 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001040DictionaryListKeys(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001041{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001042 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001043 long_u todo = dict->dv_hashtab.ht_used;
1044 Py_ssize_t i = 0;
1045 PyObject *r;
1046 hashitem_T *hi;
1047
1048 r = PyList_New(todo);
1049 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1050 {
1051 if (!HASHITEM_EMPTY(hi))
1052 {
1053 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
1054 --todo;
1055 ++i;
1056 }
1057 }
1058 return r;
1059}
1060
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001061static PyMappingMethods DictionaryAsMapping = {
1062 (lenfunc) DictionaryLength,
1063 (binaryfunc) DictionaryItem,
1064 (objobjargproc) DictionaryAssItem,
1065};
1066
Bram Moolenaardb913952012-06-29 12:54:53 +02001067static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001068 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001069 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
1070 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001071};
1072
1073static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001074static PySequenceMethods ListAsSeq;
1075static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +02001076
1077typedef struct
1078{
1079 PyObject_HEAD
1080 list_T *list;
1081 pylinkedlist_T ref;
1082} ListObject;
1083
1084 static PyObject *
1085ListNew(list_T *list)
1086{
1087 ListObject *self;
1088
1089 self = PyObject_NEW(ListObject, &ListType);
1090 if (self == NULL)
1091 return NULL;
1092 self->list = list;
1093 ++list->lv_refcount;
1094
1095 pyll_add((PyObject *)(self), &self->ref, &lastlist);
1096
1097 return (PyObject *)(self);
1098}
1099
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001100 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001101ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001102{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001103 pyll_remove(&self->ref, &lastlist);
1104 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001105
1106 DESTRUCTOR_FINISH(self);
1107}
1108
Bram Moolenaardb913952012-06-29 12:54:53 +02001109 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001110list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001111{
1112 Py_ssize_t i;
1113 Py_ssize_t lsize = PySequence_Size(obj);
1114 PyObject *litem;
1115 listitem_T *li;
1116
1117 for(i=0; i<lsize; i++)
1118 {
1119 li = listitem_alloc();
1120 if (li == NULL)
1121 {
1122 PyErr_NoMemory();
1123 return -1;
1124 }
1125 li->li_tv.v_lock = 0;
1126
1127 litem = PySequence_GetItem(obj, i);
1128 if (litem == NULL)
1129 return -1;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001130 if (_ConvertFromPyObject(litem, &li->li_tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02001131 return -1;
1132
1133 list_append(l, li);
1134 }
1135 return 0;
1136}
1137
Bram Moolenaardb913952012-06-29 12:54:53 +02001138 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001139ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001140{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001141 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02001142}
1143
1144 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001145ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02001146{
1147 listitem_T *li;
1148
Bram Moolenaard6e39182013-05-21 18:30:34 +02001149 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02001150 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001151 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001152 return NULL;
1153 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02001154 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02001155 if (li == NULL)
1156 {
1157 PyErr_SetVim(_("internal error: failed to get vim list item"));
1158 return NULL;
1159 }
1160 return ConvertToPyObject(&li->li_tv);
1161}
1162
1163#define PROC_RANGE \
1164 if (last < 0) {\
1165 if (last < -size) \
1166 last = 0; \
1167 else \
1168 last += size; \
1169 } \
1170 if (first < 0) \
1171 first = 0; \
1172 if (first > size) \
1173 first = size; \
1174 if (last > size) \
1175 last = size;
1176
1177 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001178ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02001179{
1180 PyInt i;
1181 PyInt size = ListLength(self);
1182 PyInt n;
1183 PyObject *list;
1184 int reversed = 0;
1185
1186 PROC_RANGE
1187 if (first >= last)
1188 first = last;
1189
1190 n = last-first;
1191 list = PyList_New(n);
1192 if (list == NULL)
1193 return NULL;
1194
1195 for (i = 0; i < n; ++i)
1196 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02001197 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02001198 if (item == NULL)
1199 {
1200 Py_DECREF(list);
1201 return NULL;
1202 }
1203
1204 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1205 {
1206 Py_DECREF(item);
1207 Py_DECREF(list);
1208 return NULL;
1209 }
1210 }
1211
1212 return list;
1213}
1214
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001215typedef struct
1216{
1217 listwatch_T lw;
1218 list_T *list;
1219} listiterinfo_T;
1220
1221 static void
1222ListIterDestruct(listiterinfo_T *lii)
1223{
1224 list_rem_watch(lii->list, &lii->lw);
1225 PyMem_Free(lii);
1226}
1227
1228 static PyObject *
1229ListIterNext(listiterinfo_T **lii)
1230{
1231 PyObject *r;
1232
1233 if (!((*lii)->lw.lw_item))
1234 return NULL;
1235
1236 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1237 return NULL;
1238
1239 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1240
1241 return r;
1242}
1243
1244 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001245ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001246{
1247 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001248 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001249
1250 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1251 {
1252 PyErr_NoMemory();
1253 return NULL;
1254 }
1255
1256 list_add_watch(l, &lii->lw);
1257 lii->lw.lw_item = l->lv_first;
1258 lii->list = l;
1259
1260 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001261 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
1262 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001263}
1264
Bram Moolenaardb913952012-06-29 12:54:53 +02001265 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001266ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001267{
1268 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001269 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001270 listitem_T *li;
1271 Py_ssize_t length = ListLength(self);
1272
1273 if (l->lv_lock)
1274 {
1275 PyErr_SetVim(_("list is locked"));
1276 return -1;
1277 }
1278 if (index>length || (index==length && obj==NULL))
1279 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001280 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001281 return -1;
1282 }
1283
1284 if (obj == NULL)
1285 {
1286 li = list_find(l, (long) index);
1287 list_remove(l, li, li);
1288 clear_tv(&li->li_tv);
1289 vim_free(li);
1290 return 0;
1291 }
1292
1293 if (ConvertFromPyObject(obj, &tv) == -1)
1294 return -1;
1295
1296 if (index == length)
1297 {
1298 if (list_append_tv(l, &tv) == FAIL)
1299 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001300 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001301 PyErr_SetVim(_("Failed to add item to list"));
1302 return -1;
1303 }
1304 }
1305 else
1306 {
1307 li = list_find(l, (long) index);
1308 clear_tv(&li->li_tv);
1309 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001310 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001311 }
1312 return 0;
1313}
1314
1315 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001316ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001317{
1318 PyInt size = ListLength(self);
1319 Py_ssize_t i;
1320 Py_ssize_t lsize;
1321 PyObject *litem;
1322 listitem_T *li;
1323 listitem_T *next;
1324 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001325 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001326
1327 if (l->lv_lock)
1328 {
1329 PyErr_SetVim(_("list is locked"));
1330 return -1;
1331 }
1332
1333 PROC_RANGE
1334
1335 if (first == size)
1336 li = NULL;
1337 else
1338 {
1339 li = list_find(l, (long) first);
1340 if (li == NULL)
1341 {
1342 PyErr_SetVim(_("internal error: no vim list item"));
1343 return -1;
1344 }
1345 if (last > first)
1346 {
1347 i = last - first;
1348 while (i-- && li != NULL)
1349 {
1350 next = li->li_next;
1351 listitem_remove(l, li);
1352 li = next;
1353 }
1354 }
1355 }
1356
1357 if (obj == NULL)
1358 return 0;
1359
1360 if (!PyList_Check(obj))
1361 {
1362 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1363 return -1;
1364 }
1365
1366 lsize = PyList_Size(obj);
1367
1368 for(i=0; i<lsize; i++)
1369 {
1370 litem = PyList_GetItem(obj, i);
1371 if (litem == NULL)
1372 return -1;
1373 if (ConvertFromPyObject(litem, &v) == -1)
1374 return -1;
1375 if (list_insert_tv(l, &v, li) == FAIL)
1376 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001377 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001378 PyErr_SetVim(_("internal error: failed to add item to list"));
1379 return -1;
1380 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001381 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001382 }
1383 return 0;
1384}
1385
1386 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001387ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001388{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001389 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001390 PyObject *lookup_dict;
1391
1392 if (l->lv_lock)
1393 {
1394 PyErr_SetVim(_("list is locked"));
1395 return NULL;
1396 }
1397
1398 if (!PySequence_Check(obj))
1399 {
1400 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1401 return NULL;
1402 }
1403
1404 lookup_dict = PyDict_New();
1405 if (list_py_concat(l, obj, lookup_dict) == -1)
1406 {
1407 Py_DECREF(lookup_dict);
1408 return NULL;
1409 }
1410 Py_DECREF(lookup_dict);
1411
1412 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02001413 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02001414}
1415
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001416static char *ListAttrs[] = {
1417 "locked",
1418 NULL
1419};
1420
1421 static PyObject *
1422ListDir(PyObject *self)
1423{
1424 return ObjectDir(self, ListAttrs);
1425}
1426
Bram Moolenaar66b79852012-09-21 14:00:35 +02001427 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001428ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001429{
1430 if (val == NULL)
1431 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001432 PyErr_SetString(PyExc_AttributeError,
1433 _("cannot delete vim.dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001434 return -1;
1435 }
1436
1437 if (strcmp(name, "locked") == 0)
1438 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001439 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001440 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001441 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001442 return -1;
1443 }
1444 else
1445 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001446 int istrue = PyObject_IsTrue(val);
1447 if (istrue == -1)
1448 return -1;
1449 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001450 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001451 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001452 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001453 }
1454 return 0;
1455 }
1456 else
1457 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001458 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001459 return -1;
1460 }
1461}
1462
Bram Moolenaardb913952012-06-29 12:54:53 +02001463static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001464 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1465 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
1466 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001467};
1468
1469typedef struct
1470{
1471 PyObject_HEAD
1472 char_u *name;
1473} FunctionObject;
1474
1475static PyTypeObject FunctionType;
1476
1477 static PyObject *
1478FunctionNew(char_u *name)
1479{
1480 FunctionObject *self;
1481
1482 self = PyObject_NEW(FunctionObject, &FunctionType);
1483 if (self == NULL)
1484 return NULL;
1485 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1486 if (self->name == NULL)
1487 {
1488 PyErr_NoMemory();
1489 return NULL;
1490 }
1491 STRCPY(self->name, name);
1492 func_ref(name);
1493 return (PyObject *)(self);
1494}
1495
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001496 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001497FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001498{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001499 func_unref(self->name);
1500 PyMem_Free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001501
1502 DESTRUCTOR_FINISH(self);
1503}
1504
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001505static char *FunctionAttrs[] = {
1506 "softspace",
1507 NULL
1508};
1509
1510 static PyObject *
1511FunctionDir(PyObject *self)
1512{
1513 return ObjectDir(self, FunctionAttrs);
1514}
1515
Bram Moolenaardb913952012-06-29 12:54:53 +02001516 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001517FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02001518{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001519 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02001520 typval_T args;
1521 typval_T selfdicttv;
1522 typval_T rettv;
1523 dict_T *selfdict = NULL;
1524 PyObject *selfdictObject;
1525 PyObject *result;
1526 int error;
1527
1528 if (ConvertFromPyObject(argsObject, &args) == -1)
1529 return NULL;
1530
1531 if (kwargs != NULL)
1532 {
1533 selfdictObject = PyDict_GetItemString(kwargs, "self");
1534 if (selfdictObject != NULL)
1535 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001536 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001537 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001538 PyErr_SetString(PyExc_TypeError,
1539 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001540 clear_tv(&args);
1541 return NULL;
1542 }
1543 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001544 {
1545 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02001546 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001547 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001548 selfdict = selfdicttv.vval.v_dict;
1549 }
1550 }
1551
Bram Moolenaar71700b82013-05-15 17:49:05 +02001552 Py_BEGIN_ALLOW_THREADS
1553 Python_Lock_Vim();
1554
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001555 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02001556 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02001557
1558 Python_Release_Vim();
1559 Py_END_ALLOW_THREADS
1560
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001561 if (VimTryEnd())
1562 result = NULL;
1563 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02001564 {
1565 result = NULL;
1566 PyErr_SetVim(_("failed to run function"));
1567 }
1568 else
1569 result = ConvertToPyObject(&rettv);
1570
Bram Moolenaardb913952012-06-29 12:54:53 +02001571 clear_tv(&args);
1572 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001573 if (selfdict != NULL)
1574 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001575
1576 return result;
1577}
1578
1579static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001580 {"__call__",(PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1581 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
1582 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001583};
1584
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001585/*
1586 * Options object
1587 */
1588
1589static PyTypeObject OptionsType;
1590
1591typedef int (*checkfun)(void *);
1592
1593typedef struct
1594{
1595 PyObject_HEAD
1596 int opt_type;
1597 void *from;
1598 checkfun Check;
1599 PyObject *fromObj;
1600} OptionsObject;
1601
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001602 static int
1603dummy_check(void *arg UNUSED)
1604{
1605 return 0;
1606}
1607
1608 static PyObject *
1609OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1610{
1611 OptionsObject *self;
1612
Bram Moolenaar774267b2013-05-21 20:51:59 +02001613 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001614 if (self == NULL)
1615 return NULL;
1616
1617 self->opt_type = opt_type;
1618 self->from = from;
1619 self->Check = Check;
1620 self->fromObj = fromObj;
1621 if (fromObj)
1622 Py_INCREF(fromObj);
1623
1624 return (PyObject *)(self);
1625}
1626
1627 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001628OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001629{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001630 PyObject_GC_UnTrack((void *)(self));
1631 Py_XDECREF(self->fromObj);
1632 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001633}
1634
1635 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001636OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001637{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001638 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001639 return 0;
1640}
1641
1642 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001643OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001644{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001645 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001646 return 0;
1647}
1648
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001649 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001650OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001651{
1652 char_u *key;
1653 int flags;
1654 long numval;
1655 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001656 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001657
Bram Moolenaard6e39182013-05-21 18:30:34 +02001658 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001659 return NULL;
1660
Bram Moolenaara03e6312013-05-29 22:49:26 +02001661 DICTKEY_GET(NULL, 0)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001662
1663 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001664 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001665
1666 DICTKEY_UNREF
1667
1668 if (flags == 0)
1669 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001670 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001671 return NULL;
1672 }
1673
1674 if (flags & SOPT_UNSET)
1675 {
1676 Py_INCREF(Py_None);
1677 return Py_None;
1678 }
1679 else if (flags & SOPT_BOOL)
1680 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001681 PyObject *r;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001682 r = numval ? Py_True : Py_False;
1683 Py_INCREF(r);
1684 return r;
1685 }
1686 else if (flags & SOPT_NUM)
1687 return PyInt_FromLong(numval);
1688 else if (flags & SOPT_STRING)
1689 {
1690 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001691 {
1692 PyObject *r = PyBytes_FromString((char *) stringval);
1693 vim_free(stringval);
1694 return r;
1695 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001696 else
1697 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001698 PyErr_SetString(PyExc_RuntimeError,
1699 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001700 return NULL;
1701 }
1702 }
1703 else
1704 {
1705 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1706 return NULL;
1707 }
1708}
1709
1710 static int
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001711set_option_value_err(key, numval, stringval, opt_flags)
1712 char_u *key;
1713 int numval;
1714 char_u *stringval;
1715 int opt_flags;
1716{
1717 char_u *errmsg;
1718
1719 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
1720 {
1721 if (VimTryEnd())
1722 return FAIL;
1723 PyErr_SetVim((char *)errmsg);
1724 return FAIL;
1725 }
1726 return OK;
1727}
1728
1729 static int
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001730set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1731 char_u *key;
1732 int numval;
1733 char_u *stringval;
1734 int opt_flags;
1735 int opt_type;
1736 void *from;
1737{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001738 win_T *save_curwin = NULL;
1739 tabpage_T *save_curtab = NULL;
1740 buf_T *save_curbuf = NULL;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001741 int r = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001742
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001743 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001744 switch (opt_type)
1745 {
1746 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001747 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
1748 win_find_tabpage((win_T *)from)) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001749 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001750 if (VimTryEnd())
1751 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001752 PyErr_SetVim("Problem while switching windows.");
1753 return -1;
1754 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001755 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001756 restore_win(save_curwin, save_curtab);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001757 if (r == FAIL)
1758 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001759 break;
1760 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001761 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001762 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02001763 restore_buffer(save_curbuf);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001764 if (r == FAIL)
1765 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001766 break;
1767 case SREQ_GLOBAL:
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001768 r = set_option_value_err(key, numval, stringval, opt_flags);
1769 if (r == FAIL)
1770 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001771 break;
1772 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001773 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001774}
1775
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001776 static void *
1777py_memsave(void *p, size_t len)
1778{
1779 void *r;
1780 if (!(r = PyMem_Malloc(len)))
1781 return NULL;
1782 mch_memmove(r, p, len);
1783 return r;
1784}
1785
1786#define PY_STRSAVE(s) ((char_u *) py_memsave(s, STRLEN(s) + 1))
1787
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001788 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001789OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001790{
1791 char_u *key;
1792 int flags;
1793 int opt_flags;
1794 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001795 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001796
Bram Moolenaard6e39182013-05-21 18:30:34 +02001797 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001798 return -1;
1799
Bram Moolenaara03e6312013-05-29 22:49:26 +02001800 DICTKEY_GET(-1, 0)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001801
1802 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001803 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001804
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001805 if (flags == 0)
1806 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001807 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001808 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001809 return -1;
1810 }
1811
1812 if (valObject == NULL)
1813 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001814 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001815 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001816 PyErr_SetString(PyExc_ValueError,
1817 _("unable to unset global option"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001818 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001819 return -1;
1820 }
1821 else if (!(flags & SOPT_GLOBAL))
1822 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001823 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
1824 "without global value"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001825 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001826 return -1;
1827 }
1828 else
1829 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001830 unset_global_local_option(key, self->from);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001831 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001832 return 0;
1833 }
1834 }
1835
Bram Moolenaard6e39182013-05-21 18:30:34 +02001836 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001837
1838 if (flags & SOPT_BOOL)
1839 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001840 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001841
Bram Moolenaarb983f752013-05-15 16:11:50 +02001842 if (istrue == -1)
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001843 r = -1;
1844 else
1845 r = set_option_value_for(key, istrue, NULL,
1846 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001847 }
1848 else if (flags & SOPT_NUM)
1849 {
1850 int val;
1851
1852#if PY_MAJOR_VERSION < 3
1853 if (PyInt_Check(valObject))
1854 val = PyInt_AsLong(valObject);
1855 else
1856#endif
1857 if (PyLong_Check(valObject))
1858 val = PyLong_AsLong(valObject);
1859 else
1860 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001861 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001862 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001863 return -1;
1864 }
1865
1866 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001867 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001868 }
1869 else
1870 {
1871 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001872 PyObject *todecref;
1873
1874 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001875 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001876 r = set_option_value_for(key, 0, val, opt_flags,
1877 self->opt_type, self->from);
1878 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001879 }
1880 else
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001881 r = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001882 }
1883
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001884 DICTKEY_UNREF
1885
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001886 return r;
1887}
1888
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001889static PyMappingMethods OptionsAsMapping = {
1890 (lenfunc) NULL,
1891 (binaryfunc) OptionsItem,
1892 (objobjargproc) OptionsAssItem,
1893};
1894
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001895/* Tabpage object
1896 */
1897
1898typedef struct
1899{
1900 PyObject_HEAD
1901 tabpage_T *tab;
1902} TabPageObject;
1903
1904static PyObject *WinListNew(TabPageObject *tabObject);
1905
1906static PyTypeObject TabPageType;
1907
1908 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001909CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001910{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001911 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001912 {
1913 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1914 return -1;
1915 }
1916
1917 return 0;
1918}
1919
1920 static PyObject *
1921TabPageNew(tabpage_T *tab)
1922{
1923 TabPageObject *self;
1924
1925 if (TAB_PYTHON_REF(tab))
1926 {
1927 self = TAB_PYTHON_REF(tab);
1928 Py_INCREF(self);
1929 }
1930 else
1931 {
1932 self = PyObject_NEW(TabPageObject, &TabPageType);
1933 if (self == NULL)
1934 return NULL;
1935 self->tab = tab;
1936 TAB_PYTHON_REF(tab) = self;
1937 }
1938
1939 return (PyObject *)(self);
1940}
1941
1942 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001943TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001944{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001945 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
1946 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001947
1948 DESTRUCTOR_FINISH(self);
1949}
1950
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001951static char *TabPageAttrs[] = {
1952 "windows", "number", "vars", "window", "valid",
1953 NULL
1954};
1955
1956 static PyObject *
1957TabPageDir(PyObject *self)
1958{
1959 return ObjectDir(self, TabPageAttrs);
1960}
1961
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001962 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02001963TabPageAttrValid(TabPageObject *self, char *name)
1964{
1965 PyObject *r;
1966
1967 if (strcmp(name, "valid") != 0)
1968 return NULL;
1969
1970 r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
1971 Py_INCREF(r);
1972 return r;
1973}
1974
1975 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001976TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001977{
1978 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001979 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001980 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001981 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001982 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001983 return DictionaryNew(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001984 else if (strcmp(name, "window") == 0)
1985 {
1986 /* For current tab window.c does not bother to set or update tp_curwin
1987 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001988 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001989 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001990 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001991 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001992 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001993 else if (strcmp(name, "__members__") == 0)
1994 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001995 return NULL;
1996}
1997
1998 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001999TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002000{
2001 static char repr[100];
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002002
Bram Moolenaard6e39182013-05-21 18:30:34 +02002003 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002004 {
2005 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
2006 return PyString_FromString(repr);
2007 }
2008 else
2009 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002010 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002011
2012 if (t == 0)
2013 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
2014 (self));
2015 else
2016 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
2017
2018 return PyString_FromString(repr);
2019 }
2020}
2021
2022static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002023 /* name, function, calling, documentation */
2024 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
2025 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002026};
2027
2028/*
2029 * Window list object
2030 */
2031
2032static PyTypeObject TabListType;
2033static PySequenceMethods TabListAsSeq;
2034
2035typedef struct
2036{
2037 PyObject_HEAD
2038} TabListObject;
2039
2040 static PyInt
2041TabListLength(PyObject *self UNUSED)
2042{
2043 tabpage_T *tp = first_tabpage;
2044 PyInt n = 0;
2045
2046 while (tp != NULL)
2047 {
2048 ++n;
2049 tp = tp->tp_next;
2050 }
2051
2052 return n;
2053}
2054
2055 static PyObject *
2056TabListItem(PyObject *self UNUSED, PyInt n)
2057{
2058 tabpage_T *tp;
2059
2060 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
2061 if (n == 0)
2062 return TabPageNew(tp);
2063
2064 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
2065 return NULL;
2066}
2067
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002068/* Window object
2069 */
2070
2071typedef struct
2072{
2073 PyObject_HEAD
2074 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002075 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002076} WindowObject;
2077
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002078static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002079
2080 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002081CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002082{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002083 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002084 {
2085 PyErr_SetVim(_("attempt to refer to deleted window"));
2086 return -1;
2087 }
2088
2089 return 0;
2090}
2091
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002092 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002093WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02002094{
2095 /* We need to handle deletion of windows underneath us.
2096 * If we add a "w_python*_ref" field to the win_T structure,
2097 * then we can get at it in win_free() in vim. We then
2098 * need to create only ONE Python object per window - if
2099 * we try to create a second, just INCREF the existing one
2100 * and return it. The (single) Python object referring to
2101 * the window is stored in "w_python*_ref".
2102 * On a win_free() we set the Python object's win_T* field
2103 * to an invalid value. We trap all uses of a window
2104 * object, and reject them if the win_T* field is invalid.
2105 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002106 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002107 * w_python_ref and w_python3_ref fields respectively.
2108 */
2109
2110 WindowObject *self;
2111
2112 if (WIN_PYTHON_REF(win))
2113 {
2114 self = WIN_PYTHON_REF(win);
2115 Py_INCREF(self);
2116 }
2117 else
2118 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02002119 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02002120 if (self == NULL)
2121 return NULL;
2122 self->win = win;
2123 WIN_PYTHON_REF(win) = self;
2124 }
2125
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002126 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
2127
Bram Moolenaar971db462013-05-12 18:44:48 +02002128 return (PyObject *)(self);
2129}
2130
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002131 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002132WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002133{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002134 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02002135 if (self->win && self->win != INVALID_WINDOW_VALUE)
2136 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02002137 Py_XDECREF(((PyObject *)(self->tabObject)));
2138 PyObject_GC_Del((void *)(self));
2139}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002140
Bram Moolenaar774267b2013-05-21 20:51:59 +02002141 static int
2142WindowTraverse(WindowObject *self, visitproc visit, void *arg)
2143{
2144 Py_VISIT(((PyObject *)(self->tabObject)));
2145 return 0;
2146}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002147
Bram Moolenaar774267b2013-05-21 20:51:59 +02002148 static int
2149WindowClear(WindowObject *self)
2150{
2151 Py_CLEAR(self->tabObject);
2152 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002153}
2154
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002155 static win_T *
2156get_firstwin(TabPageObject *tabObject)
2157{
2158 if (tabObject)
2159 {
2160 if (CheckTabPage(tabObject))
2161 return NULL;
2162 /* For current tab window.c does not bother to set or update tp_firstwin
2163 */
2164 else if (tabObject->tab == curtab)
2165 return firstwin;
2166 else
2167 return tabObject->tab->tp_firstwin;
2168 }
2169 else
2170 return firstwin;
2171}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002172static char *WindowAttrs[] = {
2173 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
2174 "tabpage", "valid",
2175 NULL
2176};
2177
2178 static PyObject *
2179WindowDir(PyObject *self)
2180{
2181 return ObjectDir(self, WindowAttrs);
2182}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002183
Bram Moolenaar971db462013-05-12 18:44:48 +02002184 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002185WindowAttrValid(WindowObject *self, char *name)
2186{
2187 PyObject *r;
2188
2189 if (strcmp(name, "valid") != 0)
2190 return NULL;
2191
2192 r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
2193 Py_INCREF(r);
2194 return r;
2195}
2196
2197 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002198WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002199{
2200 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002201 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002202 else if (strcmp(name, "cursor") == 0)
2203 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002204 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002205
2206 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2207 }
2208 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002209 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002210#ifdef FEAT_WINDOWS
2211 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002212 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002213#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002214#ifdef FEAT_VERTSPLIT
2215 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002216 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002217 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002218 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002219#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02002220 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002221 return DictionaryNew(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002222 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002223 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
2224 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02002225 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002226 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002227 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002228 return NULL;
2229 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002230 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002231 }
2232 else if (strcmp(name, "tabpage") == 0)
2233 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002234 Py_INCREF(self->tabObject);
2235 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002236 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002237 else if (strcmp(name, "__members__") == 0)
2238 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002239 else
2240 return NULL;
2241}
2242
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002243 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002244WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002245{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002246 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002247 return -1;
2248
2249 if (strcmp(name, "buffer") == 0)
2250 {
2251 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2252 return -1;
2253 }
2254 else if (strcmp(name, "cursor") == 0)
2255 {
2256 long lnum;
2257 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002258
2259 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2260 return -1;
2261
Bram Moolenaard6e39182013-05-21 18:30:34 +02002262 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002263 {
2264 PyErr_SetVim(_("cursor position outside buffer"));
2265 return -1;
2266 }
2267
2268 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002269 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002270 return -1;
2271
Bram Moolenaard6e39182013-05-21 18:30:34 +02002272 self->win->w_cursor.lnum = lnum;
2273 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002274#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02002275 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002276#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002277 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002278 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002279
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002280 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002281 return 0;
2282 }
2283 else if (strcmp(name, "height") == 0)
2284 {
2285 int height;
2286 win_T *savewin;
2287
2288 if (!PyArg_Parse(val, "i", &height))
2289 return -1;
2290
2291#ifdef FEAT_GUI
2292 need_mouse_correct = TRUE;
2293#endif
2294 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002295 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002296
2297 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002298 win_setheight(height);
2299 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002300 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002301 return -1;
2302
2303 return 0;
2304 }
2305#ifdef FEAT_VERTSPLIT
2306 else if (strcmp(name, "width") == 0)
2307 {
2308 int width;
2309 win_T *savewin;
2310
2311 if (!PyArg_Parse(val, "i", &width))
2312 return -1;
2313
2314#ifdef FEAT_GUI
2315 need_mouse_correct = TRUE;
2316#endif
2317 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002318 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002319
2320 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002321 win_setwidth(width);
2322 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002323 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002324 return -1;
2325
2326 return 0;
2327 }
2328#endif
2329 else
2330 {
2331 PyErr_SetString(PyExc_AttributeError, name);
2332 return -1;
2333 }
2334}
2335
2336 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002337WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002338{
2339 static char repr[100];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002340
Bram Moolenaard6e39182013-05-21 18:30:34 +02002341 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002342 {
2343 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2344 return PyString_FromString(repr);
2345 }
2346 else
2347 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002348 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002349
Bram Moolenaar6d216452013-05-12 19:00:41 +02002350 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002351 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2352 (self));
2353 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02002354 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002355
2356 return PyString_FromString(repr);
2357 }
2358}
2359
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002360static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002361 /* name, function, calling, documentation */
2362 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
2363 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002364};
2365
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002366/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002367 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002368 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002369
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002370static PyTypeObject WinListType;
2371static PySequenceMethods WinListAsSeq;
2372
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002373typedef struct
2374{
2375 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002376 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002377} WinListObject;
2378
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002379 static PyObject *
2380WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002381{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002382 WinListObject *self;
2383
2384 self = PyObject_NEW(WinListObject, &WinListType);
2385 self->tabObject = tabObject;
2386 Py_INCREF(tabObject);
2387
2388 return (PyObject *)(self);
2389}
2390
2391 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002392WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002393{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002394 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002395
2396 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02002397 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002398 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02002399 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002400
2401 DESTRUCTOR_FINISH(self);
2402}
2403
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002404 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002405WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002406{
2407 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002408 PyInt n = 0;
2409
Bram Moolenaard6e39182013-05-21 18:30:34 +02002410 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002411 return -1;
2412
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002413 while (w != NULL)
2414 {
2415 ++n;
2416 w = W_NEXT(w);
2417 }
2418
2419 return n;
2420}
2421
2422 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002423WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002424{
2425 win_T *w;
2426
Bram Moolenaard6e39182013-05-21 18:30:34 +02002427 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002428 return NULL;
2429
2430 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002431 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002432 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002433
2434 PyErr_SetString(PyExc_IndexError, _("no such window"));
2435 return NULL;
2436}
2437
2438/* Convert a Python string into a Vim line.
2439 *
2440 * The result is in allocated memory. All internal nulls are replaced by
2441 * newline characters. It is an error for the string to contain newline
2442 * characters.
2443 *
2444 * On errors, the Python exception data is set, and NULL is returned.
2445 */
2446 static char *
2447StringToLine(PyObject *obj)
2448{
2449 const char *str;
2450 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002451 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002452 PyInt len;
2453 PyInt i;
2454 char *p;
2455
2456 if (obj == NULL || !PyString_Check(obj))
2457 {
2458 PyErr_BadArgument();
2459 return NULL;
2460 }
2461
Bram Moolenaar19e60942011-06-19 00:27:51 +02002462 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2463 str = PyString_AsString(bytes);
2464 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002465
2466 /*
2467 * Error checking: String must not contain newlines, as we
2468 * are replacing a single line, and we must replace it with
2469 * a single line.
2470 * A trailing newline is removed, so that append(f.readlines()) works.
2471 */
2472 p = memchr(str, '\n', len);
2473 if (p != NULL)
2474 {
2475 if (p == str + len - 1)
2476 --len;
2477 else
2478 {
2479 PyErr_SetVim(_("string cannot contain newlines"));
2480 return NULL;
2481 }
2482 }
2483
2484 /* Create a copy of the string, with internal nulls replaced by
2485 * newline characters, as is the vim convention.
2486 */
2487 save = (char *)alloc((unsigned)(len+1));
2488 if (save == NULL)
2489 {
2490 PyErr_NoMemory();
2491 return NULL;
2492 }
2493
2494 for (i = 0; i < len; ++i)
2495 {
2496 if (str[i] == '\0')
2497 save[i] = '\n';
2498 else
2499 save[i] = str[i];
2500 }
2501
2502 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002503 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002504
2505 return save;
2506}
2507
2508/* Get a line from the specified buffer. The line number is
2509 * in Vim format (1-based). The line is returned as a Python
2510 * string object.
2511 */
2512 static PyObject *
2513GetBufferLine(buf_T *buf, PyInt n)
2514{
2515 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2516}
2517
2518
2519/* Get a list of lines from the specified buffer. The line numbers
2520 * are in Vim format (1-based). The range is from lo up to, but not
2521 * including, hi. The list is returned as a Python list of string objects.
2522 */
2523 static PyObject *
2524GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2525{
2526 PyInt i;
2527 PyInt n = hi - lo;
2528 PyObject *list = PyList_New(n);
2529
2530 if (list == NULL)
2531 return NULL;
2532
2533 for (i = 0; i < n; ++i)
2534 {
2535 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2536
2537 /* Error check - was the Python string creation OK? */
2538 if (str == NULL)
2539 {
2540 Py_DECREF(list);
2541 return NULL;
2542 }
2543
2544 /* Set the list item */
2545 if (PyList_SetItem(list, i, str))
2546 {
2547 Py_DECREF(str);
2548 Py_DECREF(list);
2549 return NULL;
2550 }
2551 }
2552
2553 /* The ownership of the Python list is passed to the caller (ie,
2554 * the caller should Py_DECREF() the object when it is finished
2555 * with it).
2556 */
2557
2558 return list;
2559}
2560
2561/*
2562 * Check if deleting lines made the cursor position invalid.
2563 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2564 * deleted).
2565 */
2566 static void
2567py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2568{
2569 if (curwin->w_cursor.lnum >= lo)
2570 {
2571 /* Adjust the cursor position if it's in/after the changed
2572 * lines. */
2573 if (curwin->w_cursor.lnum >= hi)
2574 {
2575 curwin->w_cursor.lnum += extra;
2576 check_cursor_col();
2577 }
2578 else if (extra < 0)
2579 {
2580 curwin->w_cursor.lnum = lo;
2581 check_cursor();
2582 }
2583 else
2584 check_cursor_col();
2585 changed_cline_bef_curs();
2586 }
2587 invalidate_botline();
2588}
2589
Bram Moolenaar19e60942011-06-19 00:27:51 +02002590/*
2591 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002592 * in Vim format (1-based). The replacement line is given as
2593 * a Python string object. The object is checked for validity
2594 * and correct format. Errors are returned as a value of FAIL.
2595 * The return value is OK on success.
2596 * If OK is returned and len_change is not NULL, *len_change
2597 * is set to the change in the buffer length.
2598 */
2599 static int
2600SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2601{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002602 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002603 * There are three cases:
2604 * 1. NULL, or None - this is a deletion.
2605 * 2. A string - this is a replacement.
2606 * 3. Anything else - this is an error.
2607 */
2608 if (line == Py_None || line == NULL)
2609 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002610 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002611
2612 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002613 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002614
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002615 VimTryStart();
2616
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002617 if (u_savedel((linenr_T)n, 1L) == FAIL)
2618 PyErr_SetVim(_("cannot save undo information"));
2619 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2620 PyErr_SetVim(_("cannot delete line"));
2621 else
2622 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002623 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002624 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2625 deleted_lines_mark((linenr_T)n, 1L);
2626 }
2627
Bram Moolenaar105bc352013-05-17 16:03:57 +02002628 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002629
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002630 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002631 return FAIL;
2632
2633 if (len_change)
2634 *len_change = -1;
2635
2636 return OK;
2637 }
2638 else if (PyString_Check(line))
2639 {
2640 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002641 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002642
2643 if (save == NULL)
2644 return FAIL;
2645
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002646 VimTryStart();
2647
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002648 /* We do not need to free "save" if ml_replace() consumes it. */
2649 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002650 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002651
2652 if (u_savesub((linenr_T)n) == FAIL)
2653 {
2654 PyErr_SetVim(_("cannot save undo information"));
2655 vim_free(save);
2656 }
2657 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2658 {
2659 PyErr_SetVim(_("cannot replace line"));
2660 vim_free(save);
2661 }
2662 else
2663 changed_bytes((linenr_T)n, 0);
2664
Bram Moolenaar105bc352013-05-17 16:03:57 +02002665 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002666
2667 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02002668 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002669 check_cursor_col();
2670
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002671 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002672 return FAIL;
2673
2674 if (len_change)
2675 *len_change = 0;
2676
2677 return OK;
2678 }
2679 else
2680 {
2681 PyErr_BadArgument();
2682 return FAIL;
2683 }
2684}
2685
Bram Moolenaar19e60942011-06-19 00:27:51 +02002686/* Replace a range of lines in the specified buffer. The line numbers are in
2687 * Vim format (1-based). The range is from lo up to, but not including, hi.
2688 * The replacement lines are given as a Python list of string objects. The
2689 * list is checked for validity and correct format. Errors are returned as a
2690 * value of FAIL. The return value is OK on success.
2691 * If OK is returned and len_change is not NULL, *len_change
2692 * is set to the change in the buffer length.
2693 */
2694 static int
2695SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2696{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002697 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002698 * There are three cases:
2699 * 1. NULL, or None - this is a deletion.
2700 * 2. A list - this is a replacement.
2701 * 3. Anything else - this is an error.
2702 */
2703 if (list == Py_None || list == NULL)
2704 {
2705 PyInt i;
2706 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002707 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002708
2709 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002710 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002711 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002712
2713 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2714 PyErr_SetVim(_("cannot save undo information"));
2715 else
2716 {
2717 for (i = 0; i < n; ++i)
2718 {
2719 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2720 {
2721 PyErr_SetVim(_("cannot delete line"));
2722 break;
2723 }
2724 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02002725 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002726 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2727 deleted_lines_mark((linenr_T)lo, (long)i);
2728 }
2729
Bram Moolenaar105bc352013-05-17 16:03:57 +02002730 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002731
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002732 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002733 return FAIL;
2734
2735 if (len_change)
2736 *len_change = -n;
2737
2738 return OK;
2739 }
2740 else if (PyList_Check(list))
2741 {
2742 PyInt i;
2743 PyInt new_len = PyList_Size(list);
2744 PyInt old_len = hi - lo;
2745 PyInt extra = 0; /* lines added to text, can be negative */
2746 char **array;
2747 buf_T *savebuf;
2748
2749 if (new_len == 0) /* avoid allocating zero bytes */
2750 array = NULL;
2751 else
2752 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002753 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002754 if (array == NULL)
2755 {
2756 PyErr_NoMemory();
2757 return FAIL;
2758 }
2759 }
2760
2761 for (i = 0; i < new_len; ++i)
2762 {
2763 PyObject *line = PyList_GetItem(list, i);
2764
2765 array[i] = StringToLine(line);
2766 if (array[i] == NULL)
2767 {
2768 while (i)
2769 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002770 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002771 return FAIL;
2772 }
2773 }
2774
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002775 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02002776 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002777
2778 // START of region without "return". Must call restore_buffer()!
2779 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002780
2781 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2782 PyErr_SetVim(_("cannot save undo information"));
2783
2784 /* If the size of the range is reducing (ie, new_len < old_len) we
2785 * need to delete some old_len. We do this at the start, by
2786 * repeatedly deleting line "lo".
2787 */
2788 if (!PyErr_Occurred())
2789 {
2790 for (i = 0; i < old_len - new_len; ++i)
2791 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2792 {
2793 PyErr_SetVim(_("cannot delete line"));
2794 break;
2795 }
2796 extra -= i;
2797 }
2798
2799 /* For as long as possible, replace the existing old_len with the
2800 * new old_len. This is a more efficient operation, as it requires
2801 * less memory allocation and freeing.
2802 */
2803 if (!PyErr_Occurred())
2804 {
2805 for (i = 0; i < old_len && i < new_len; ++i)
2806 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2807 == FAIL)
2808 {
2809 PyErr_SetVim(_("cannot replace line"));
2810 break;
2811 }
2812 }
2813 else
2814 i = 0;
2815
2816 /* Now we may need to insert the remaining new old_len. If we do, we
2817 * must free the strings as we finish with them (we can't pass the
2818 * responsibility to vim in this case).
2819 */
2820 if (!PyErr_Occurred())
2821 {
2822 while (i < new_len)
2823 {
2824 if (ml_append((linenr_T)(lo + i - 1),
2825 (char_u *)array[i], 0, FALSE) == FAIL)
2826 {
2827 PyErr_SetVim(_("cannot insert line"));
2828 break;
2829 }
2830 vim_free(array[i]);
2831 ++i;
2832 ++extra;
2833 }
2834 }
2835
2836 /* Free any left-over old_len, as a result of an error */
2837 while (i < new_len)
2838 {
2839 vim_free(array[i]);
2840 ++i;
2841 }
2842
2843 /* Free the array of old_len. All of its contents have now
2844 * been dealt with (either freed, or the responsibility passed
2845 * to vim.
2846 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002847 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002848
2849 /* Adjust marks. Invalidate any which lie in the
2850 * changed range, and move any in the remainder of the buffer.
2851 */
2852 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2853 (long)MAXLNUM, (long)extra);
2854 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2855
Bram Moolenaar105bc352013-05-17 16:03:57 +02002856 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002857 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2858
Bram Moolenaar105bc352013-05-17 16:03:57 +02002859 // END of region without "return".
2860 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002861
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002862 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002863 return FAIL;
2864
2865 if (len_change)
2866 *len_change = new_len - old_len;
2867
2868 return OK;
2869 }
2870 else
2871 {
2872 PyErr_BadArgument();
2873 return FAIL;
2874 }
2875}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002876
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002877/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002878 * The line number is in Vim format (1-based). The lines to be inserted are
2879 * given as a Python list of string objects or as a single string. The lines
2880 * to be added are checked for validity and correct format. Errors are
2881 * returned as a value of FAIL. The return value is OK on success.
2882 * If OK is returned and len_change is not NULL, *len_change
2883 * is set to the change in the buffer length.
2884 */
2885 static int
2886InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2887{
2888 /* First of all, we check the type of the supplied Python object.
2889 * It must be a string or a list, or the call is in error.
2890 */
2891 if (PyString_Check(lines))
2892 {
2893 char *str = StringToLine(lines);
2894 buf_T *savebuf;
2895
2896 if (str == NULL)
2897 return FAIL;
2898
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002899 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002900 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002901 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002902
2903 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2904 PyErr_SetVim(_("cannot save undo information"));
2905 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2906 PyErr_SetVim(_("cannot insert line"));
2907 else
2908 appended_lines_mark((linenr_T)n, 1L);
2909
2910 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002911 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002912 update_screen(VALID);
2913
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002914 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002915 return FAIL;
2916
2917 if (len_change)
2918 *len_change = 1;
2919
2920 return OK;
2921 }
2922 else if (PyList_Check(lines))
2923 {
2924 PyInt i;
2925 PyInt size = PyList_Size(lines);
2926 char **array;
2927 buf_T *savebuf;
2928
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002929 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002930 if (array == NULL)
2931 {
2932 PyErr_NoMemory();
2933 return FAIL;
2934 }
2935
2936 for (i = 0; i < size; ++i)
2937 {
2938 PyObject *line = PyList_GetItem(lines, i);
2939 array[i] = StringToLine(line);
2940
2941 if (array[i] == NULL)
2942 {
2943 while (i)
2944 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002945 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002946 return FAIL;
2947 }
2948 }
2949
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002950 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002951 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002952 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002953
2954 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2955 PyErr_SetVim(_("cannot save undo information"));
2956 else
2957 {
2958 for (i = 0; i < size; ++i)
2959 {
2960 if (ml_append((linenr_T)(n + i),
2961 (char_u *)array[i], 0, FALSE) == FAIL)
2962 {
2963 PyErr_SetVim(_("cannot insert line"));
2964
2965 /* Free the rest of the lines */
2966 while (i < size)
2967 vim_free(array[i++]);
2968
2969 break;
2970 }
2971 vim_free(array[i]);
2972 }
2973 if (i > 0)
2974 appended_lines_mark((linenr_T)n, (long)i);
2975 }
2976
2977 /* Free the array of lines. All of its contents have now
2978 * been freed.
2979 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002980 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002981
Bram Moolenaar105bc352013-05-17 16:03:57 +02002982 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002983 update_screen(VALID);
2984
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002985 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002986 return FAIL;
2987
2988 if (len_change)
2989 *len_change = size;
2990
2991 return OK;
2992 }
2993 else
2994 {
2995 PyErr_BadArgument();
2996 return FAIL;
2997 }
2998}
2999
3000/*
3001 * Common routines for buffers and line ranges
3002 * -------------------------------------------
3003 */
3004
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003005typedef struct
3006{
3007 PyObject_HEAD
3008 buf_T *buf;
3009} BufferObject;
3010
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003011 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003012CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003013{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003014 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003015 {
3016 PyErr_SetVim(_("attempt to refer to deleted buffer"));
3017 return -1;
3018 }
3019
3020 return 0;
3021}
3022
3023 static PyObject *
3024RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
3025{
3026 if (CheckBuffer(self))
3027 return NULL;
3028
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003029 if (end == -1)
3030 end = self->buf->b_ml.ml_line_count;
3031
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003032 if (n < 0)
3033 n += end - start + 1;
3034
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003035 if (n < 0 || n > end - start)
3036 {
3037 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3038 return NULL;
3039 }
3040
3041 return GetBufferLine(self->buf, n+start);
3042}
3043
3044 static PyObject *
3045RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
3046{
3047 PyInt size;
3048
3049 if (CheckBuffer(self))
3050 return NULL;
3051
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003052 if (end == -1)
3053 end = self->buf->b_ml.ml_line_count;
3054
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003055 size = end - start + 1;
3056
3057 if (lo < 0)
3058 lo = 0;
3059 else if (lo > size)
3060 lo = size;
3061 if (hi < 0)
3062 hi = 0;
3063 if (hi < lo)
3064 hi = lo;
3065 else if (hi > size)
3066 hi = size;
3067
3068 return GetBufferLineList(self->buf, lo+start, hi+start);
3069}
3070
3071 static PyInt
3072RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3073{
3074 PyInt len_change;
3075
3076 if (CheckBuffer(self))
3077 return -1;
3078
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003079 if (end == -1)
3080 end = self->buf->b_ml.ml_line_count;
3081
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003082 if (n < 0)
3083 n += end - start + 1;
3084
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003085 if (n < 0 || n > end - start)
3086 {
3087 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3088 return -1;
3089 }
3090
3091 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
3092 return -1;
3093
3094 if (new_end)
3095 *new_end = end + len_change;
3096
3097 return 0;
3098}
3099
Bram Moolenaar19e60942011-06-19 00:27:51 +02003100 static PyInt
3101RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3102{
3103 PyInt size;
3104 PyInt len_change;
3105
3106 /* Self must be a valid buffer */
3107 if (CheckBuffer(self))
3108 return -1;
3109
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003110 if (end == -1)
3111 end = self->buf->b_ml.ml_line_count;
3112
Bram Moolenaar19e60942011-06-19 00:27:51 +02003113 /* Sort out the slice range */
3114 size = end - start + 1;
3115
3116 if (lo < 0)
3117 lo = 0;
3118 else if (lo > size)
3119 lo = size;
3120 if (hi < 0)
3121 hi = 0;
3122 if (hi < lo)
3123 hi = lo;
3124 else if (hi > size)
3125 hi = size;
3126
3127 if (SetBufferLineList(self->buf, lo + start, hi + start,
3128 val, &len_change) == FAIL)
3129 return -1;
3130
3131 if (new_end)
3132 *new_end = end + len_change;
3133
3134 return 0;
3135}
3136
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003137
3138 static PyObject *
3139RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
3140{
3141 PyObject *lines;
3142 PyInt len_change;
3143 PyInt max;
3144 PyInt n;
3145
3146 if (CheckBuffer(self))
3147 return NULL;
3148
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003149 if (end == -1)
3150 end = self->buf->b_ml.ml_line_count;
3151
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003152 max = n = end - start + 1;
3153
3154 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
3155 return NULL;
3156
3157 if (n < 0 || n > max)
3158 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003159 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003160 return NULL;
3161 }
3162
3163 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
3164 return NULL;
3165
3166 if (new_end)
3167 *new_end = end + len_change;
3168
3169 Py_INCREF(Py_None);
3170 return Py_None;
3171}
3172
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003173/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003174 */
3175
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003176static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003177static PySequenceMethods RangeAsSeq;
3178static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003179
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003180typedef struct
3181{
3182 PyObject_HEAD
3183 BufferObject *buf;
3184 PyInt start;
3185 PyInt end;
3186} RangeObject;
3187
3188 static PyObject *
3189RangeNew(buf_T *buf, PyInt start, PyInt end)
3190{
3191 BufferObject *bufr;
3192 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003193 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003194 if (self == NULL)
3195 return NULL;
3196
3197 bufr = (BufferObject *)BufferNew(buf);
3198 if (bufr == NULL)
3199 {
3200 Py_DECREF(self);
3201 return NULL;
3202 }
3203 Py_INCREF(bufr);
3204
3205 self->buf = bufr;
3206 self->start = start;
3207 self->end = end;
3208
3209 return (PyObject *)(self);
3210}
3211
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003212 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003213RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003214{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003215 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003216 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02003217 PyObject_GC_Del((void *)(self));
3218}
3219
3220 static int
3221RangeTraverse(RangeObject *self, visitproc visit, void *arg)
3222{
3223 Py_VISIT(((PyObject *)(self->buf)));
3224 return 0;
3225}
3226
3227 static int
3228RangeClear(RangeObject *self)
3229{
3230 Py_CLEAR(self->buf);
3231 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003232}
3233
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003234 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003235RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003236{
3237 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003238 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003239 return -1; /* ??? */
3240
Bram Moolenaard6e39182013-05-21 18:30:34 +02003241 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003242}
3243
3244 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003245RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003246{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003247 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003248}
3249
3250 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003251RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003252{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003253 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003254}
3255
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003256static char *RangeAttrs[] = {
3257 "start", "end",
3258 NULL
3259};
3260
3261 static PyObject *
3262RangeDir(PyObject *self)
3263{
3264 return ObjectDir(self, RangeAttrs);
3265}
3266
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003267 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003268RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003269{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003270 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003271}
3272
3273 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003274RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003275{
3276 static char repr[100];
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003277
Bram Moolenaard6e39182013-05-21 18:30:34 +02003278 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003279 {
3280 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
3281 (self));
3282 return PyString_FromString(repr);
3283 }
3284 else
3285 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003286 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003287 int len;
3288
3289 if (name == NULL)
3290 name = "";
3291 len = (int)strlen(name);
3292
3293 if (len > 45)
3294 name = name + (45 - len);
3295
3296 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
3297 len > 45 ? "..." : "", name,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003298 self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003299
3300 return PyString_FromString(repr);
3301 }
3302}
3303
3304static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003305 /* name, function, calling, documentation */
3306 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003307 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
3308 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003309};
3310
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003311static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003312static PySequenceMethods BufferAsSeq;
3313static PyMappingMethods BufferAsMapping;
3314
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003315 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02003316BufferNew(buf_T *buf)
3317{
3318 /* We need to handle deletion of buffers underneath us.
3319 * If we add a "b_python*_ref" field to the buf_T structure,
3320 * then we can get at it in buf_freeall() in vim. We then
3321 * need to create only ONE Python object per buffer - if
3322 * we try to create a second, just INCREF the existing one
3323 * and return it. The (single) Python object referring to
3324 * the buffer is stored in "b_python*_ref".
3325 * Question: what to do on a buf_freeall(). We'll probably
3326 * have to either delete the Python object (DECREF it to
3327 * zero - a bad idea, as it leaves dangling refs!) or
3328 * set the buf_T * value to an invalid value (-1?), which
3329 * means we need checks in all access functions... Bah.
3330 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003331 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003332 * b_python_ref and b_python3_ref fields respectively.
3333 */
3334
3335 BufferObject *self;
3336
3337 if (BUF_PYTHON_REF(buf) != NULL)
3338 {
3339 self = BUF_PYTHON_REF(buf);
3340 Py_INCREF(self);
3341 }
3342 else
3343 {
3344 self = PyObject_NEW(BufferObject, &BufferType);
3345 if (self == NULL)
3346 return NULL;
3347 self->buf = buf;
3348 BUF_PYTHON_REF(buf) = self;
3349 }
3350
3351 return (PyObject *)(self);
3352}
3353
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003354 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003355BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003356{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003357 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3358 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003359
3360 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003361}
3362
Bram Moolenaar971db462013-05-12 18:44:48 +02003363 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003364BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003365{
3366 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003367 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003368 return -1; /* ??? */
3369
Bram Moolenaard6e39182013-05-21 18:30:34 +02003370 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003371}
3372
3373 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003374BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003375{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003376 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003377}
3378
3379 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003380BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003381{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003382 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003383}
3384
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003385static char *BufferAttrs[] = {
3386 "name", "number", "vars", "options", "valid",
3387 NULL
3388};
3389
3390 static PyObject *
3391BufferDir(PyObject *self)
3392{
3393 return ObjectDir(self, BufferAttrs);
3394}
3395
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003396 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003397BufferAttrValid(BufferObject *self, char *name)
3398{
3399 PyObject *r;
3400
3401 if (strcmp(name, "valid") != 0)
3402 return NULL;
3403
3404 r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
3405 Py_INCREF(r);
3406 return r;
3407}
3408
3409 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003410BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003411{
3412 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02003413 return PyString_FromString((self->buf->b_ffname == NULL
3414 ? "" : (char *) self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003415 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003416 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003417 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003418 return DictionaryNew(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003419 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003420 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3421 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003422 else if (strcmp(name, "__members__") == 0)
3423 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003424 else
3425 return NULL;
3426}
3427
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003428 static int
3429BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
3430{
3431 if (CheckBuffer(self))
3432 return -1;
3433
3434 if (strcmp(name, "name") == 0)
3435 {
3436 char_u *val;
3437 aco_save_T aco;
3438 int r;
3439 PyObject *todecref;
3440
3441 if (!(val = StringToChars(valObject, &todecref)))
3442 return -1;
3443
3444 VimTryStart();
3445 /* Using aucmd_*: autocommands will be executed by rename_buffer */
3446 aucmd_prepbuf(&aco, self->buf);
3447 r = rename_buffer(val);
3448 aucmd_restbuf(&aco);
3449 Py_XDECREF(todecref);
3450 if (VimTryEnd())
3451 return -1;
3452
3453 if (r == FAIL)
3454 {
3455 PyErr_SetVim(_("failed to rename buffer"));
3456 return -1;
3457 }
3458 return 0;
3459 }
3460 else
3461 {
3462 PyErr_SetString(PyExc_AttributeError, name);
3463 return -1;
3464 }
3465}
3466
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003467 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003468BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003469{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003470 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003471}
3472
3473 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003474BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003475{
3476 pos_T *posp;
3477 char *pmark;
3478 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02003479 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003480
Bram Moolenaard6e39182013-05-21 18:30:34 +02003481 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003482 return NULL;
3483
3484 if (!PyArg_ParseTuple(args, "s", &pmark))
3485 return NULL;
3486 mark = *pmark;
3487
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003488 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02003489 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003490 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003491 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003492 if (VimTryEnd())
3493 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003494
3495 if (posp == NULL)
3496 {
3497 PyErr_SetVim(_("invalid mark name"));
3498 return NULL;
3499 }
3500
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003501 if (posp->lnum <= 0)
3502 {
3503 /* Or raise an error? */
3504 Py_INCREF(Py_None);
3505 return Py_None;
3506 }
3507
3508 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3509}
3510
3511 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003512BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003513{
3514 PyInt start;
3515 PyInt end;
3516
Bram Moolenaard6e39182013-05-21 18:30:34 +02003517 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003518 return NULL;
3519
3520 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3521 return NULL;
3522
Bram Moolenaard6e39182013-05-21 18:30:34 +02003523 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003524}
3525
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003526 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003527BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003528{
3529 static char repr[100];
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003530
Bram Moolenaard6e39182013-05-21 18:30:34 +02003531 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003532 {
3533 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3534 return PyString_FromString(repr);
3535 }
3536 else
3537 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003538 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003539 PyInt len;
3540
3541 if (name == NULL)
3542 name = "";
3543 len = strlen(name);
3544
3545 if (len > 35)
3546 name = name + (35 - len);
3547
3548 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3549
3550 return PyString_FromString(repr);
3551 }
3552}
3553
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003554static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003555 /* name, function, calling, documentation */
3556 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
3557 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
3558 {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003559 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
3560 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003561};
3562
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003563/*
3564 * Buffer list object - Implementation
3565 */
3566
3567static PyTypeObject BufMapType;
3568
3569typedef struct
3570{
3571 PyObject_HEAD
3572} BufMapObject;
3573
3574 static PyInt
3575BufMapLength(PyObject *self UNUSED)
3576{
3577 buf_T *b = firstbuf;
3578 PyInt n = 0;
3579
3580 while (b)
3581 {
3582 ++n;
3583 b = b->b_next;
3584 }
3585
3586 return n;
3587}
3588
3589 static PyObject *
3590BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3591{
3592 buf_T *b;
3593 int bnr;
3594
3595#if PY_MAJOR_VERSION < 3
3596 if (PyInt_Check(keyObject))
3597 bnr = PyInt_AsLong(keyObject);
3598 else
3599#endif
3600 if (PyLong_Check(keyObject))
3601 bnr = PyLong_AsLong(keyObject);
3602 else
3603 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003604 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003605 return NULL;
3606 }
3607
3608 b = buflist_findnr(bnr);
3609
3610 if (b)
3611 return BufferNew(b);
3612 else
3613 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003614 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003615 return NULL;
3616 }
3617}
3618
3619 static void
3620BufMapIterDestruct(PyObject *buffer)
3621{
3622 /* Iteration was stopped before all buffers were processed */
3623 if (buffer)
3624 {
3625 Py_DECREF(buffer);
3626 }
3627}
3628
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003629 static int
3630BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
3631{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003632 if (buffer)
3633 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003634 return 0;
3635}
3636
3637 static int
3638BufMapIterClear(PyObject **buffer)
3639{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003640 if (*buffer)
3641 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003642 return 0;
3643}
3644
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003645 static PyObject *
3646BufMapIterNext(PyObject **buffer)
3647{
3648 PyObject *next;
3649 PyObject *r;
3650
3651 if (!*buffer)
3652 return NULL;
3653
3654 r = *buffer;
3655
3656 if (CheckBuffer((BufferObject *)(r)))
3657 {
3658 *buffer = NULL;
3659 return NULL;
3660 }
3661
3662 if (!((BufferObject *)(r))->buf->b_next)
3663 next = NULL;
3664 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3665 return NULL;
3666 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02003667 /* Do not increment reference: we no longer hold it (decref), but whoever
3668 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003669 return r;
3670}
3671
3672 static PyObject *
3673BufMapIter(PyObject *self UNUSED)
3674{
3675 PyObject *buffer;
3676
3677 buffer = BufferNew(firstbuf);
3678 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003679 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
3680 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003681}
3682
3683static PyMappingMethods BufMapAsMapping = {
3684 (lenfunc) BufMapLength,
3685 (binaryfunc) BufMapItem,
3686 (objobjargproc) 0,
3687};
3688
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003689/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003690 */
3691
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003692static char *CurrentAttrs[] = {
3693 "buffer", "window", "line", "range", "tabpage",
3694 NULL
3695};
3696
3697 static PyObject *
3698CurrentDir(PyObject *self)
3699{
3700 return ObjectDir(self, CurrentAttrs);
3701}
3702
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003703 static PyObject *
3704CurrentGetattr(PyObject *self UNUSED, char *name)
3705{
3706 if (strcmp(name, "buffer") == 0)
3707 return (PyObject *)BufferNew(curbuf);
3708 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003709 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003710 else if (strcmp(name, "tabpage") == 0)
3711 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003712 else if (strcmp(name, "line") == 0)
3713 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3714 else if (strcmp(name, "range") == 0)
3715 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003716 else if (strcmp(name, "__members__") == 0)
3717 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003718 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003719#if PY_MAJOR_VERSION < 3
3720 return Py_FindMethod(WindowMethods, self, name);
3721#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003722 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003723#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003724}
3725
3726 static int
3727CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3728{
3729 if (strcmp(name, "line") == 0)
3730 {
3731 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3732 return -1;
3733
3734 return 0;
3735 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003736 else if (strcmp(name, "buffer") == 0)
3737 {
3738 int count;
3739
3740 if (value->ob_type != &BufferType)
3741 {
3742 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3743 return -1;
3744 }
3745
3746 if (CheckBuffer((BufferObject *)(value)))
3747 return -1;
3748 count = ((BufferObject *)(value))->buf->b_fnum;
3749
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003750 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003751 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3752 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003753 if (VimTryEnd())
3754 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003755 PyErr_SetVim(_("failed to switch to given buffer"));
3756 return -1;
3757 }
3758
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003759 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003760 }
3761 else if (strcmp(name, "window") == 0)
3762 {
3763 int count;
3764
3765 if (value->ob_type != &WindowType)
3766 {
3767 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3768 return -1;
3769 }
3770
3771 if (CheckWindow((WindowObject *)(value)))
3772 return -1;
3773 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3774
3775 if (!count)
3776 {
3777 PyErr_SetString(PyExc_ValueError,
3778 _("failed to find window in the current tab page"));
3779 return -1;
3780 }
3781
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003782 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003783 win_goto(((WindowObject *)(value))->win);
3784 if (((WindowObject *)(value))->win != curwin)
3785 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003786 if (VimTryEnd())
3787 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003788 PyErr_SetString(PyExc_RuntimeError,
3789 _("did not switch to the specified window"));
3790 return -1;
3791 }
3792
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003793 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003794 }
3795 else if (strcmp(name, "tabpage") == 0)
3796 {
3797 if (value->ob_type != &TabPageType)
3798 {
3799 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3800 return -1;
3801 }
3802
3803 if (CheckTabPage((TabPageObject *)(value)))
3804 return -1;
3805
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003806 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003807 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3808 if (((TabPageObject *)(value))->tab != curtab)
3809 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003810 if (VimTryEnd())
3811 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003812 PyErr_SetString(PyExc_RuntimeError,
3813 _("did not switch to the specified tab page"));
3814 return -1;
3815 }
3816
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003817 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003818 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003819 else
3820 {
3821 PyErr_SetString(PyExc_AttributeError, name);
3822 return -1;
3823 }
3824}
3825
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003826static struct PyMethodDef CurrentMethods[] = {
3827 /* name, function, calling, documentation */
3828 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
3829 { NULL, NULL, 0, NULL}
3830};
3831
Bram Moolenaardb913952012-06-29 12:54:53 +02003832 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003833init_range_cmd(exarg_T *eap)
3834{
3835 RangeStart = eap->line1;
3836 RangeEnd = eap->line2;
3837}
3838
3839 static void
3840init_range_eval(typval_T *rettv UNUSED)
3841{
3842 RangeStart = (PyInt) curwin->w_cursor.lnum;
3843 RangeEnd = RangeStart;
3844}
3845
3846 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003847run_cmd(const char *cmd, void *arg UNUSED
3848#ifdef PY_CAN_RECURSE
3849 , PyGILState_STATE *pygilstate UNUSED
3850#endif
3851 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003852{
3853 PyRun_SimpleString((char *) cmd);
3854}
3855
3856static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
3857static int code_hdr_len = 30;
3858
3859 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003860run_do(const char *cmd, void *arg UNUSED
3861#ifdef PY_CAN_RECURSE
3862 , PyGILState_STATE *pygilstate
3863#endif
3864 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003865{
3866 PyInt lnum;
3867 size_t len;
3868 char *code;
3869 int status;
3870 PyObject *pyfunc, *pymain;
3871
Bram Moolenaar4ac66762013-05-28 22:31:46 +02003872 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003873 {
3874 EMSG(_("cannot save undo information"));
3875 return;
3876 }
3877
3878 len = code_hdr_len + STRLEN(cmd);
3879 code = PyMem_New(char, len + 1);
3880 memcpy(code, code_hdr, code_hdr_len);
3881 STRCPY(code + code_hdr_len, cmd);
3882 status = PyRun_SimpleString(code);
3883 PyMem_Free(code);
3884
3885 if (status)
3886 {
3887 EMSG(_("failed to run the code"));
3888 return;
3889 }
3890
3891 status = 0;
3892 pymain = PyImport_AddModule("__main__");
3893 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003894#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003895 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003896#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003897
3898 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
3899 {
3900 PyObject *line, *linenr, *ret;
3901
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003902#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003903 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003904#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003905 if (!(line = GetBufferLine(curbuf, lnum)))
3906 goto err;
3907 if (!(linenr = PyInt_FromLong((long) lnum)))
3908 {
3909 Py_DECREF(line);
3910 goto err;
3911 }
3912 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
3913 Py_DECREF(line);
3914 Py_DECREF(linenr);
3915 if (!ret)
3916 goto err;
3917
3918 if (ret != Py_None)
3919 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
3920 goto err;
3921
3922 Py_XDECREF(ret);
3923 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003924#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003925 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003926#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003927 }
3928 goto out;
3929err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003930#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003931 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003932#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003933 PyErr_PrintEx(0);
3934 PythonIO_Flush();
3935 status = 1;
3936out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003937#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003938 if (!status)
3939 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003940#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003941 Py_DECREF(pyfunc);
3942 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
3943 if (status)
3944 return;
3945 check_cursor();
3946 update_curbuf(NOT_VALID);
3947}
3948
3949 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003950run_eval(const char *cmd, typval_T *rettv
3951#ifdef PY_CAN_RECURSE
3952 , PyGILState_STATE *pygilstate UNUSED
3953#endif
3954 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003955{
3956 PyObject *r;
3957
3958 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
3959 if (r == NULL)
3960 {
3961 if (PyErr_Occurred() && !msg_silent)
3962 PyErr_PrintEx(0);
3963 EMSG(_("E858: Eval did not return a valid python object"));
3964 }
3965 else
3966 {
3967 if (ConvertFromPyObject(r, rettv) == -1)
3968 EMSG(_("E859: Failed to convert returned python object to vim value"));
3969 Py_DECREF(r);
3970 }
3971 PyErr_Clear();
3972}
3973
3974 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02003975set_ref_in_py(const int copyID)
3976{
3977 pylinkedlist_T *cur;
3978 dict_T *dd;
3979 list_T *ll;
3980
3981 if (lastdict != NULL)
3982 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3983 {
3984 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3985 if (dd->dv_copyID != copyID)
3986 {
3987 dd->dv_copyID = copyID;
3988 set_ref_in_ht(&dd->dv_hashtab, copyID);
3989 }
3990 }
3991
3992 if (lastlist != NULL)
3993 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3994 {
3995 ll = ((ListObject *) (cur->pll_obj))->list;
3996 if (ll->lv_copyID != copyID)
3997 {
3998 ll->lv_copyID = copyID;
3999 set_ref_in_list(ll, copyID);
4000 }
4001 }
4002}
4003
4004 static int
4005set_string_copy(char_u *str, typval_T *tv)
4006{
4007 tv->vval.v_string = vim_strsave(str);
4008 if (tv->vval.v_string == NULL)
4009 {
4010 PyErr_NoMemory();
4011 return -1;
4012 }
4013 return 0;
4014}
4015
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004016 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004017pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004018{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004019 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004020 char_u *key;
4021 dictitem_T *di;
4022 PyObject *keyObject;
4023 PyObject *valObject;
4024 Py_ssize_t iter = 0;
4025
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004026 dict = dict_alloc();
4027 if (dict == NULL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004028 {
4029 PyErr_NoMemory();
4030 return -1;
4031 }
4032
4033 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004034 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004035
4036 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
4037 {
4038 DICTKEY_DECL
4039
Bram Moolenaara03e6312013-05-29 22:49:26 +02004040 if (keyObject == NULL || valObject == NULL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004041 return -1;
4042
Bram Moolenaara03e6312013-05-29 22:49:26 +02004043 DICTKEY_GET(-1, 0)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004044
4045 di = dictitem_alloc(key);
4046
4047 DICTKEY_UNREF
4048
4049 if (di == NULL)
4050 {
4051 PyErr_NoMemory();
4052 return -1;
4053 }
4054 di->di_tv.v_lock = 0;
4055
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004056 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004057 {
4058 vim_free(di);
4059 return -1;
4060 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004061
4062 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004063 {
Bram Moolenaara03e6312013-05-29 22:49:26 +02004064 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004065 vim_free(di);
4066 PyErr_SetVim(_("failed to add key to dictionary"));
4067 return -1;
4068 }
4069 }
4070 return 0;
4071}
4072
4073 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004074pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004075{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004076 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004077 char_u *key;
4078 dictitem_T *di;
4079 PyObject *list;
4080 PyObject *litem;
4081 PyObject *keyObject;
4082 PyObject *valObject;
4083 Py_ssize_t lsize;
4084
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004085 dict = dict_alloc();
4086 if (dict == NULL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004087 {
4088 PyErr_NoMemory();
4089 return -1;
4090 }
4091
4092 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004093 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004094
4095 list = PyMapping_Items(obj);
4096 if (list == NULL)
4097 return -1;
4098 lsize = PyList_Size(list);
4099 while (lsize--)
4100 {
4101 DICTKEY_DECL
4102
4103 litem = PyList_GetItem(list, lsize);
4104 if (litem == NULL)
4105 {
4106 Py_DECREF(list);
4107 return -1;
4108 }
4109
Bram Moolenaara03e6312013-05-29 22:49:26 +02004110 if (!(keyObject = PyTuple_GetItem(litem, 0)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004111 {
4112 Py_DECREF(list);
4113 Py_DECREF(litem);
4114 return -1;
4115 }
4116
Bram Moolenaara03e6312013-05-29 22:49:26 +02004117 DICTKEY_GET(-1, 1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004118
Bram Moolenaara03e6312013-05-29 22:49:26 +02004119 if (!(valObject = PyTuple_GetItem(litem, 1)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004120 {
4121 Py_DECREF(list);
4122 Py_DECREF(litem);
Bram Moolenaara03e6312013-05-29 22:49:26 +02004123 DICTKEY_UNREF
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004124 return -1;
4125 }
4126
Bram Moolenaara03e6312013-05-29 22:49:26 +02004127 Py_DECREF(litem);
4128
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004129 di = dictitem_alloc(key);
4130
4131 DICTKEY_UNREF
4132
4133 if (di == NULL)
4134 {
4135 Py_DECREF(list);
Bram Moolenaara03e6312013-05-29 22:49:26 +02004136 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004137 PyErr_NoMemory();
4138 return -1;
4139 }
4140 di->di_tv.v_lock = 0;
4141
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004142 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004143 {
4144 vim_free(di);
4145 Py_DECREF(list);
Bram Moolenaara03e6312013-05-29 22:49:26 +02004146 Py_DECREF(valObject);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004147 return -1;
4148 }
Bram Moolenaara03e6312013-05-29 22:49:26 +02004149
4150 Py_DECREF(valObject);
4151
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004152 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004153 {
Bram Moolenaara03e6312013-05-29 22:49:26 +02004154 clear_tv(&di->di_tv);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004155 vim_free(di);
4156 Py_DECREF(list);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004157 PyErr_SetVim(_("failed to add key to dictionary"));
4158 return -1;
4159 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004160 }
4161 Py_DECREF(list);
4162 return 0;
4163}
4164
4165 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004166pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004167{
4168 list_T *l;
4169
4170 l = list_alloc();
4171 if (l == NULL)
4172 {
4173 PyErr_NoMemory();
4174 return -1;
4175 }
4176
4177 tv->v_type = VAR_LIST;
4178 tv->vval.v_list = l;
4179
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004180 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004181 return -1;
4182
4183 return 0;
4184}
4185
4186 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004187pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004188{
4189 PyObject *iterator = PyObject_GetIter(obj);
4190 PyObject *item;
4191 list_T *l;
4192 listitem_T *li;
4193
4194 l = list_alloc();
4195
4196 if (l == NULL)
4197 {
4198 PyErr_NoMemory();
4199 return -1;
4200 }
4201
4202 tv->vval.v_list = l;
4203 tv->v_type = VAR_LIST;
4204
4205
4206 if (iterator == NULL)
4207 return -1;
4208
Bram Moolenaarc8366792013-05-29 22:46:26 +02004209 while ((item = PyIter_Next(iterator)))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004210 {
4211 li = listitem_alloc();
4212 if (li == NULL)
4213 {
Bram Moolenaara03e6312013-05-29 22:49:26 +02004214 Py_DECREF(iterator);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004215 PyErr_NoMemory();
4216 return -1;
4217 }
4218 li->li_tv.v_lock = 0;
4219
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004220 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
Bram Moolenaara03e6312013-05-29 22:49:26 +02004221 {
4222 Py_DECREF(item);
4223 Py_DECREF(iterator);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004224 return -1;
Bram Moolenaara03e6312013-05-29 22:49:26 +02004225 }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004226
4227 list_append(l, li);
4228
4229 Py_DECREF(item);
4230 }
4231
4232 Py_DECREF(iterator);
4233 return 0;
4234}
4235
Bram Moolenaardb913952012-06-29 12:54:53 +02004236typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
4237
4238 static int
4239convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004240 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004241{
4242 PyObject *capsule;
4243 char hexBuf[sizeof(void *) * 2 + 3];
4244
4245 sprintf(hexBuf, "%p", obj);
4246
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004247# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004248 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004249# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004250 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004251# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02004252 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02004253 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004254# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004255 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02004256# else
4257 capsule = PyCObject_FromVoidPtr(tv, NULL);
4258# endif
Bram Moolenaara03e6312013-05-29 22:49:26 +02004259 if (PyDict_SetItemString(lookup_dict, hexBuf, capsule))
4260 {
4261 Py_DECREF(capsule);
4262 tv->v_type = VAR_UNKNOWN;
4263 return -1;
4264 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004265 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02004266 {
4267 tv->v_type = VAR_UNKNOWN;
4268 return -1;
4269 }
4270 /* As we are not using copy_tv which increments reference count we must
4271 * do it ourself. */
4272 switch(tv->v_type)
4273 {
4274 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
4275 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
4276 }
4277 }
4278 else
4279 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004280 typval_T *v;
4281
4282# ifdef PY_USE_CAPSULE
4283 v = PyCapsule_GetPointer(capsule, NULL);
4284# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004285 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004286# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004287 copy_tv(v, tv);
4288 }
4289 return 0;
4290}
4291
4292 static int
4293ConvertFromPyObject(PyObject *obj, typval_T *tv)
4294{
4295 PyObject *lookup_dict;
4296 int r;
4297
4298 lookup_dict = PyDict_New();
4299 r = _ConvertFromPyObject(obj, tv, lookup_dict);
4300 Py_DECREF(lookup_dict);
4301 return r;
4302}
4303
4304 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004305_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004306{
4307 if (obj->ob_type == &DictionaryType)
4308 {
4309 tv->v_type = VAR_DICT;
4310 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4311 ++tv->vval.v_dict->dv_refcount;
4312 }
4313 else if (obj->ob_type == &ListType)
4314 {
4315 tv->v_type = VAR_LIST;
4316 tv->vval.v_list = (((ListObject *)(obj))->list);
4317 ++tv->vval.v_list->lv_refcount;
4318 }
4319 else if (obj->ob_type == &FunctionType)
4320 {
4321 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
4322 return -1;
4323
4324 tv->v_type = VAR_FUNC;
4325 func_ref(tv->vval.v_string);
4326 }
Bram Moolenaardb913952012-06-29 12:54:53 +02004327 else if (PyBytes_Check(obj))
4328 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004329 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02004330
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004331 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
4332 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004333 if (result == NULL)
4334 return -1;
4335
4336 if (set_string_copy(result, tv) == -1)
4337 return -1;
4338
4339 tv->v_type = VAR_STRING;
4340 }
4341 else if (PyUnicode_Check(obj))
4342 {
4343 PyObject *bytes;
4344 char_u *result;
4345
Bram Moolenaardb913952012-06-29 12:54:53 +02004346 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
4347 if (bytes == NULL)
4348 return -1;
4349
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004350 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
4351 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004352 if (result == NULL)
4353 return -1;
4354
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004355 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02004356 {
4357 Py_XDECREF(bytes);
4358 return -1;
4359 }
4360 Py_XDECREF(bytes);
4361
4362 tv->v_type = VAR_STRING;
4363 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02004364#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02004365 else if (PyInt_Check(obj))
4366 {
4367 tv->v_type = VAR_NUMBER;
4368 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
4369 }
4370#endif
4371 else if (PyLong_Check(obj))
4372 {
4373 tv->v_type = VAR_NUMBER;
4374 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
4375 }
4376 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004377 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004378#ifdef FEAT_FLOAT
4379 else if (PyFloat_Check(obj))
4380 {
4381 tv->v_type = VAR_FLOAT;
4382 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
4383 }
4384#endif
4385 else if (PyIter_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004386 return convert_dl(obj, tv, pyiter_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004387 else if (PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004388 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004389 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004390 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004391 else
4392 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004393 PyErr_SetString(PyExc_TypeError,
4394 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02004395 return -1;
4396 }
4397 return 0;
4398}
4399
4400 static PyObject *
4401ConvertToPyObject(typval_T *tv)
4402{
4403 if (tv == NULL)
4404 {
4405 PyErr_SetVim(_("NULL reference passed"));
4406 return NULL;
4407 }
4408 switch (tv->v_type)
4409 {
4410 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004411 return PyBytes_FromString(tv->vval.v_string == NULL
4412 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004413 case VAR_NUMBER:
4414 return PyLong_FromLong((long) tv->vval.v_number);
4415#ifdef FEAT_FLOAT
4416 case VAR_FLOAT:
4417 return PyFloat_FromDouble((double) tv->vval.v_float);
4418#endif
4419 case VAR_LIST:
4420 return ListNew(tv->vval.v_list);
4421 case VAR_DICT:
4422 return DictionaryNew(tv->vval.v_dict);
4423 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004424 return FunctionNew(tv->vval.v_string == NULL
4425 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004426 case VAR_UNKNOWN:
4427 Py_INCREF(Py_None);
4428 return Py_None;
4429 default:
4430 PyErr_SetVim(_("internal error: invalid value type"));
4431 return NULL;
4432 }
4433}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004434
4435typedef struct
4436{
4437 PyObject_HEAD
4438} CurrentObject;
4439static PyTypeObject CurrentType;
4440
4441 static void
4442init_structs(void)
4443{
4444 vim_memset(&OutputType, 0, sizeof(OutputType));
4445 OutputType.tp_name = "vim.message";
4446 OutputType.tp_basicsize = sizeof(OutputObject);
4447 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
4448 OutputType.tp_doc = "vim message object";
4449 OutputType.tp_methods = OutputMethods;
4450#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004451 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
4452 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004453 OutputType.tp_alloc = call_PyType_GenericAlloc;
4454 OutputType.tp_new = call_PyType_GenericNew;
4455 OutputType.tp_free = call_PyObject_Free;
4456#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004457 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
4458 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004459#endif
4460
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004461 vim_memset(&IterType, 0, sizeof(IterType));
4462 IterType.tp_name = "vim.iter";
4463 IterType.tp_basicsize = sizeof(IterObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02004464 IterType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004465 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004466 IterType.tp_iter = (getiterfunc)IterIter;
4467 IterType.tp_iternext = (iternextfunc)IterNext;
4468 IterType.tp_dealloc = (destructor)IterDestructor;
4469 IterType.tp_traverse = (traverseproc)IterTraverse;
4470 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004471
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004472 vim_memset(&BufferType, 0, sizeof(BufferType));
4473 BufferType.tp_name = "vim.buffer";
4474 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004475 BufferType.tp_dealloc = (destructor)BufferDestructor;
4476 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004477 BufferType.tp_as_sequence = &BufferAsSeq;
4478 BufferType.tp_as_mapping = &BufferAsMapping;
4479 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
4480 BufferType.tp_doc = "vim buffer object";
4481 BufferType.tp_methods = BufferMethods;
4482#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004483 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004484 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004485 BufferType.tp_alloc = call_PyType_GenericAlloc;
4486 BufferType.tp_new = call_PyType_GenericNew;
4487 BufferType.tp_free = call_PyObject_Free;
4488#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004489 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004490 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004491#endif
4492
4493 vim_memset(&WindowType, 0, sizeof(WindowType));
4494 WindowType.tp_name = "vim.window";
4495 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004496 WindowType.tp_dealloc = (destructor)WindowDestructor;
4497 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar07b88642013-05-29 22:58:32 +02004498 WindowType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004499 WindowType.tp_doc = "vim Window object";
4500 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004501 WindowType.tp_traverse = (traverseproc)WindowTraverse;
4502 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004503#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004504 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
4505 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004506 WindowType.tp_alloc = call_PyType_GenericAlloc;
4507 WindowType.tp_new = call_PyType_GenericNew;
4508 WindowType.tp_free = call_PyObject_Free;
4509#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004510 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
4511 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004512#endif
4513
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004514 vim_memset(&TabPageType, 0, sizeof(TabPageType));
4515 TabPageType.tp_name = "vim.tabpage";
4516 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004517 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
4518 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004519 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
4520 TabPageType.tp_doc = "vim tab page object";
4521 TabPageType.tp_methods = TabPageMethods;
4522#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004523 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004524 TabPageType.tp_alloc = call_PyType_GenericAlloc;
4525 TabPageType.tp_new = call_PyType_GenericNew;
4526 TabPageType.tp_free = call_PyObject_Free;
4527#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004528 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004529#endif
4530
Bram Moolenaardfa38d42013-05-15 13:38:47 +02004531 vim_memset(&BufMapType, 0, sizeof(BufMapType));
4532 BufMapType.tp_name = "vim.bufferlist";
4533 BufMapType.tp_basicsize = sizeof(BufMapObject);
4534 BufMapType.tp_as_mapping = &BufMapAsMapping;
4535 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004536 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004537 BufferType.tp_doc = "vim buffer list";
4538
4539 vim_memset(&WinListType, 0, sizeof(WinListType));
4540 WinListType.tp_name = "vim.windowlist";
4541 WinListType.tp_basicsize = sizeof(WinListType);
4542 WinListType.tp_as_sequence = &WinListAsSeq;
4543 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
4544 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004545 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004546
4547 vim_memset(&TabListType, 0, sizeof(TabListType));
4548 TabListType.tp_name = "vim.tabpagelist";
4549 TabListType.tp_basicsize = sizeof(TabListType);
4550 TabListType.tp_as_sequence = &TabListAsSeq;
4551 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
4552 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004553
4554 vim_memset(&RangeType, 0, sizeof(RangeType));
4555 RangeType.tp_name = "vim.range";
4556 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004557 RangeType.tp_dealloc = (destructor)RangeDestructor;
4558 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004559 RangeType.tp_as_sequence = &RangeAsSeq;
4560 RangeType.tp_as_mapping = &RangeAsMapping;
Bram Moolenaar07b88642013-05-29 22:58:32 +02004561 RangeType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004562 RangeType.tp_doc = "vim Range object";
4563 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004564 RangeType.tp_traverse = (traverseproc)RangeTraverse;
4565 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004566#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004567 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004568 RangeType.tp_alloc = call_PyType_GenericAlloc;
4569 RangeType.tp_new = call_PyType_GenericNew;
4570 RangeType.tp_free = call_PyObject_Free;
4571#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004572 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004573#endif
4574
4575 vim_memset(&CurrentType, 0, sizeof(CurrentType));
4576 CurrentType.tp_name = "vim.currentdata";
4577 CurrentType.tp_basicsize = sizeof(CurrentObject);
4578 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
4579 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004580 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004581#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004582 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
4583 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004584#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004585 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
4586 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004587#endif
4588
4589 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
4590 DictionaryType.tp_name = "vim.dictionary";
4591 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004592 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004593 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
4594 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
4595 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
4596 DictionaryType.tp_methods = DictionaryMethods;
4597#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004598 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
4599 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004600#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004601 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
4602 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004603#endif
4604
4605 vim_memset(&ListType, 0, sizeof(ListType));
4606 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004607 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004608 ListType.tp_basicsize = sizeof(ListObject);
4609 ListType.tp_as_sequence = &ListAsSeq;
4610 ListType.tp_as_mapping = &ListAsMapping;
4611 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
4612 ListType.tp_doc = "list pushing modifications to vim structure";
4613 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004614 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004615#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004616 ListType.tp_getattro = (getattrofunc)ListGetattro;
4617 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004618#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004619 ListType.tp_getattr = (getattrfunc)ListGetattr;
4620 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004621#endif
4622
4623 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004624 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004625 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004626 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
4627 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004628 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
4629 FunctionType.tp_doc = "object that calls vim function";
4630 FunctionType.tp_methods = FunctionMethods;
4631#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004632 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004633#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004634 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004635#endif
4636
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004637 vim_memset(&OptionsType, 0, sizeof(OptionsType));
4638 OptionsType.tp_name = "vim.options";
4639 OptionsType.tp_basicsize = sizeof(OptionsObject);
Bram Moolenaar07b88642013-05-29 22:58:32 +02004640 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004641 OptionsType.tp_doc = "object for manipulating options";
4642 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004643 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
4644 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
4645 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004646
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004647#if PY_MAJOR_VERSION >= 3
4648 vim_memset(&vimmodule, 0, sizeof(vimmodule));
4649 vimmodule.m_name = "vim";
4650 vimmodule.m_doc = "Vim Python interface\n";
4651 vimmodule.m_size = -1;
4652 vimmodule.m_methods = VimMethods;
4653#endif
4654}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004655
4656#define PYTYPE_READY(type) \
4657 if (PyType_Ready(&type)) \
4658 return -1;
4659
4660 static int
4661init_types()
4662{
4663 PYTYPE_READY(IterType);
4664 PYTYPE_READY(BufferType);
4665 PYTYPE_READY(RangeType);
4666 PYTYPE_READY(WindowType);
4667 PYTYPE_READY(TabPageType);
4668 PYTYPE_READY(BufMapType);
4669 PYTYPE_READY(WinListType);
4670 PYTYPE_READY(TabListType);
4671 PYTYPE_READY(CurrentType);
4672 PYTYPE_READY(DictionaryType);
4673 PYTYPE_READY(ListType);
4674 PYTYPE_READY(FunctionType);
4675 PYTYPE_READY(OptionsType);
4676 PYTYPE_READY(OutputType);
4677 return 0;
4678}
4679
4680static BufMapObject TheBufferMap =
4681{
4682 PyObject_HEAD_INIT(&BufMapType)
4683};
4684
4685static WinListObject TheWindowList =
4686{
4687 PyObject_HEAD_INIT(&WinListType)
4688 NULL
4689};
4690
4691static CurrentObject TheCurrent =
4692{
4693 PyObject_HEAD_INIT(&CurrentType)
4694};
4695
4696static TabListObject TheTabPageList =
4697{
4698 PyObject_HEAD_INIT(&TabListType)
4699};
4700
4701static struct numeric_constant {
4702 char *name;
4703 int value;
4704} numeric_constants[] = {
4705 {"VAR_LOCKED", VAR_LOCKED},
4706 {"VAR_FIXED", VAR_FIXED},
4707 {"VAR_SCOPE", VAR_SCOPE},
4708 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
4709};
4710
4711static struct object_constant {
4712 char *name;
4713 PyObject *value;
4714} object_constants[] = {
4715 {"buffers", (PyObject *)(void *)&TheBufferMap},
4716 {"windows", (PyObject *)(void *)&TheWindowList},
4717 {"tabpages", (PyObject *)(void *)&TheTabPageList},
4718 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02004719
4720 {"Buffer", (PyObject *)&BufferType},
4721 {"Range", (PyObject *)&RangeType},
4722 {"Window", (PyObject *)&WindowType},
4723 {"TabPage", (PyObject *)&TabPageType},
4724 {"Dictionary", (PyObject *)&DictionaryType},
4725 {"List", (PyObject *)&ListType},
4726 {"Function", (PyObject *)&FunctionType},
4727 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004728};
4729
4730typedef int (*object_adder)(PyObject *, const char *, PyObject *);
4731
4732#define ADD_OBJECT(m, name, obj) \
4733 if (add_object(m, name, obj)) \
4734 return -1;
4735
4736#define ADD_CHECKED_OBJECT(m, name, obj) \
4737 { \
4738 PyObject *value = obj; \
4739 if (!value) \
4740 return -1; \
4741 ADD_OBJECT(m, name, value); \
4742 }
4743
4744 static int
4745populate_module(PyObject *m, object_adder add_object)
4746{
4747 int i;
4748
4749 for (i = 0; i < (int)(sizeof(numeric_constants)
4750 / sizeof(struct numeric_constant));
4751 ++i)
4752 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
4753 PyInt_FromLong(numeric_constants[i].value));
4754
4755 for (i = 0; i < (int)(sizeof(object_constants)
4756 / sizeof(struct object_constant));
4757 ++i)
4758 {
4759 PyObject *value;
4760
4761 value = object_constants[i].value;
4762 Py_INCREF(value);
4763 ADD_OBJECT(m, object_constants[i].name, value);
4764 }
4765
4766 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
4767 return -1;
4768 ADD_OBJECT(m, "error", VimError);
4769
4770 ADD_CHECKED_OBJECT(m, "vars", DictionaryNew(&globvardict));
4771 ADD_CHECKED_OBJECT(m, "vvars", DictionaryNew(&vimvardict));
4772 ADD_CHECKED_OBJECT(m, "options",
4773 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
4774 return 0;
4775}