blob: 09bb0c060e7391805a4f6ea6bb06f380671d4d73 [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 Moolenaarb52f4c02013-05-21 18:19:38 +020033typedef void (*rangeinitializer)(void *);
34typedef void (*runner)(const char *, void *, PyGILState_STATE *);
35
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020036static int ConvertFromPyObject(PyObject *, typval_T *);
37static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020038static PyObject *WindowNew(win_T *, tabpage_T *);
39static PyObject *BufferNew (buf_T *);
40static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020041
42static PyInt RangeStart;
43static PyInt RangeEnd;
44
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020045static PyObject *globals;
46
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020047/*
48 * obtain a lock on the Vim data structures
49 */
50 static void
51Python_Lock_Vim(void)
52{
53}
54
55/*
56 * release a lock on the Vim data structures
57 */
58 static void
59Python_Release_Vim(void)
60{
61}
62
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020063/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020064 */
65
Bram Moolenaar2eea1982010-09-21 16:49:37 +020066/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020067typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020068
69static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020070
71typedef struct
72{
73 PyObject_HEAD
74 long softspace;
75 long error;
76} OutputObject;
77
Bram Moolenaar77045652012-09-21 13:46:06 +020078 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +020079OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +020080{
81 if (val == NULL)
82 {
Bram Moolenaar8661b172013-05-15 15:44:28 +020083 PyErr_SetString(PyExc_AttributeError,
84 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +020085 return -1;
86 }
87
88 if (strcmp(name, "softspace") == 0)
89 {
90 if (!PyInt_Check(val))
91 {
92 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
93 return -1;
94 }
95
Bram Moolenaard6e39182013-05-21 18:30:34 +020096 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +020097 return 0;
98 }
99
100 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
101 return -1;
102}
103
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200104/* Buffer IO, we write one whole line at a time. */
105static garray_T io_ga = {0, 0, 1, 80, NULL};
106static writefn old_fn = NULL;
107
108 static void
109PythonIO_Flush(void)
110{
111 if (old_fn != NULL && io_ga.ga_len > 0)
112 {
113 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
114 old_fn((char_u *)io_ga.ga_data);
115 }
116 io_ga.ga_len = 0;
117}
118
119 static void
120writer(writefn fn, char_u *str, PyInt n)
121{
122 char_u *ptr;
123
124 /* Flush when switching output function. */
125 if (fn != old_fn)
126 PythonIO_Flush();
127 old_fn = fn;
128
129 /* Write each NL separated line. Text after the last NL is kept for
130 * writing later. */
131 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
132 {
133 PyInt len = ptr - str;
134
135 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
136 break;
137
138 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
139 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
140 fn((char_u *)io_ga.ga_data);
141 str = ptr + 1;
142 n -= len + 1;
143 io_ga.ga_len = 0;
144 }
145
146 /* Put the remaining text into io_ga for later printing. */
147 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
148 {
149 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
150 io_ga.ga_len += (int)n;
151 }
152}
153
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200154 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200155OutputWrite(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200156{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200157 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200158 char *str = NULL;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200159 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200160
Bram Moolenaar27564802011-09-07 19:30:21 +0200161 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200162 return NULL;
163
164 Py_BEGIN_ALLOW_THREADS
165 Python_Lock_Vim();
166 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
167 Python_Release_Vim();
168 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200169 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200170
171 Py_INCREF(Py_None);
172 return Py_None;
173}
174
175 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200176OutputWritelines(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200177{
178 PyInt n;
179 PyInt i;
180 PyObject *list;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200181 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200182
183 if (!PyArg_ParseTuple(args, "O", &list))
184 return NULL;
185 Py_INCREF(list);
186
Bram Moolenaardb913952012-06-29 12:54:53 +0200187 if (!PyList_Check(list))
188 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200189 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
190 Py_DECREF(list);
191 return NULL;
192 }
193
194 n = PyList_Size(list);
195
196 for (i = 0; i < n; ++i)
197 {
198 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200199 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200200 PyInt len;
201
Bram Moolenaardb913952012-06-29 12:54:53 +0200202 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
203 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200204 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
205 Py_DECREF(list);
206 return NULL;
207 }
208
209 Py_BEGIN_ALLOW_THREADS
210 Python_Lock_Vim();
211 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
212 Python_Release_Vim();
213 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200214 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200215 }
216
217 Py_DECREF(list);
218 Py_INCREF(Py_None);
219 return Py_None;
220}
221
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100222 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200223OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100224{
225 /* do nothing */
226 Py_INCREF(Py_None);
227 return Py_None;
228}
229
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200230/***************/
231
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200232static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200233 /* name, function, calling, doc */
234 {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
235 {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
236 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
237 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200238};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200239
240static OutputObject Output =
241{
242 PyObject_HEAD_INIT(&OutputType)
243 0,
244 0
245};
246
247static OutputObject Error =
248{
249 PyObject_HEAD_INIT(&OutputType)
250 0,
251 1
252};
253
254 static int
255PythonIO_Init_io(void)
256{
257 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
258 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
259
260 if (PyErr_Occurred())
261 {
262 EMSG(_("E264: Python: Error initialising I/O objects"));
263 return -1;
264 }
265
266 return 0;
267}
268
269
270static PyObject *VimError;
271
272/* Check to see whether a Vim error has been reported, or a keyboard
273 * interrupt has been detected.
274 */
275 static int
276VimErrorCheck(void)
277{
278 if (got_int)
279 {
280 PyErr_SetNone(PyExc_KeyboardInterrupt);
281 return 1;
282 }
283 else if (did_emsg && !PyErr_Occurred())
284 {
285 PyErr_SetNone(VimError);
286 return 1;
287 }
288
289 return 0;
290}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200291
292/* Vim module - Implementation
293 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200294
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200295 static PyObject *
296VimCommand(PyObject *self UNUSED, PyObject *args)
297{
298 char *cmd;
299 PyObject *result;
300
301 if (!PyArg_ParseTuple(args, "s", &cmd))
302 return NULL;
303
304 PyErr_Clear();
305
306 Py_BEGIN_ALLOW_THREADS
307 Python_Lock_Vim();
308
309 do_cmdline_cmd((char_u *)cmd);
310 update_screen(VALID);
311
312 Python_Release_Vim();
313 Py_END_ALLOW_THREADS
314
315 if (VimErrorCheck())
316 result = NULL;
317 else
318 result = Py_None;
319
320 Py_XINCREF(result);
321 return result;
322}
323
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200324/*
325 * Function to translate a typval_T into a PyObject; this will recursively
326 * translate lists/dictionaries into their Python equivalents.
327 *
328 * The depth parameter is to avoid infinite recursion, set it to 1 when
329 * you call VimToPython.
330 */
331 static PyObject *
332VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
333{
334 PyObject *result;
335 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200336 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200337
338 /* Avoid infinite recursion */
339 if (depth > 100)
340 {
341 Py_INCREF(Py_None);
342 result = Py_None;
343 return result;
344 }
345
346 /* Check if we run into a recursive loop. The item must be in lookupDict
347 * then and we can use it again. */
348 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
349 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
350 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200351 sprintf(ptrBuf, "%p",
352 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
353 : (void *)our_tv->vval.v_dict);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200354 result = PyDict_GetItemString(lookupDict, ptrBuf);
355 if (result != NULL)
356 {
357 Py_INCREF(result);
358 return result;
359 }
360 }
361
362 if (our_tv->v_type == VAR_STRING)
363 {
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200364 result = Py_BuildValue("s", our_tv->vval.v_string == NULL
365 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200366 }
367 else if (our_tv->v_type == VAR_NUMBER)
368 {
369 char buf[NUMBUFLEN];
370
371 /* For backwards compatibility numbers are stored as strings. */
372 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
373 result = Py_BuildValue("s", buf);
374 }
375# ifdef FEAT_FLOAT
376 else if (our_tv->v_type == VAR_FLOAT)
377 {
378 char buf[NUMBUFLEN];
379
380 sprintf(buf, "%f", our_tv->vval.v_float);
381 result = Py_BuildValue("s", buf);
382 }
383# endif
384 else if (our_tv->v_type == VAR_LIST)
385 {
386 list_T *list = our_tv->vval.v_list;
387 listitem_T *curr;
388
389 result = PyList_New(0);
390
391 if (list != NULL)
392 {
393 PyDict_SetItemString(lookupDict, ptrBuf, result);
394
395 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
396 {
397 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
398 PyList_Append(result, newObj);
399 Py_DECREF(newObj);
400 }
401 }
402 }
403 else if (our_tv->v_type == VAR_DICT)
404 {
405 result = PyDict_New();
406
407 if (our_tv->vval.v_dict != NULL)
408 {
409 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
410 long_u todo = ht->ht_used;
411 hashitem_T *hi;
412 dictitem_T *di;
413
414 PyDict_SetItemString(lookupDict, ptrBuf, result);
415
416 for (hi = ht->ht_array; todo > 0; ++hi)
417 {
418 if (!HASHITEM_EMPTY(hi))
419 {
420 --todo;
421
422 di = dict_lookup(hi);
423 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
424 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
425 Py_DECREF(newObj);
426 }
427 }
428 }
429 }
430 else
431 {
432 Py_INCREF(Py_None);
433 result = Py_None;
434 }
435
436 return result;
437}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200438
439 static PyObject *
Bram Moolenaar09092152010-08-08 16:38:42 +0200440VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200441{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200442 char *expr;
443 typval_T *our_tv;
444 PyObject *result;
445 PyObject *lookup_dict;
446
447 if (!PyArg_ParseTuple(args, "s", &expr))
448 return NULL;
449
450 Py_BEGIN_ALLOW_THREADS
451 Python_Lock_Vim();
452 our_tv = eval_expr((char_u *)expr, NULL);
453
454 Python_Release_Vim();
455 Py_END_ALLOW_THREADS
456
457 if (our_tv == NULL)
458 {
459 PyErr_SetVim(_("invalid expression"));
460 return NULL;
461 }
462
463 /* Convert the Vim type into a Python type. Create a dictionary that's
464 * used to check for recursive loops. */
465 lookup_dict = PyDict_New();
466 result = VimToPython(our_tv, 1, lookup_dict);
467 Py_DECREF(lookup_dict);
468
469
470 Py_BEGIN_ALLOW_THREADS
471 Python_Lock_Vim();
472 free_tv(our_tv);
473 Python_Release_Vim();
474 Py_END_ALLOW_THREADS
475
476 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200477}
478
Bram Moolenaardb913952012-06-29 12:54:53 +0200479static PyObject *ConvertToPyObject(typval_T *);
480
481 static PyObject *
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200482VimEvalPy(PyObject *self UNUSED, PyObject *args)
Bram Moolenaardb913952012-06-29 12:54:53 +0200483{
Bram Moolenaardb913952012-06-29 12:54:53 +0200484 char *expr;
485 typval_T *our_tv;
486 PyObject *result;
487
488 if (!PyArg_ParseTuple(args, "s", &expr))
489 return NULL;
490
491 Py_BEGIN_ALLOW_THREADS
492 Python_Lock_Vim();
493 our_tv = eval_expr((char_u *)expr, NULL);
494
495 Python_Release_Vim();
496 Py_END_ALLOW_THREADS
497
498 if (our_tv == NULL)
499 {
500 PyErr_SetVim(_("invalid expression"));
501 return NULL;
502 }
503
504 result = ConvertToPyObject(our_tv);
505 Py_BEGIN_ALLOW_THREADS
506 Python_Lock_Vim();
507 free_tv(our_tv);
508 Python_Release_Vim();
509 Py_END_ALLOW_THREADS
510
511 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200512}
513
514 static PyObject *
515VimStrwidth(PyObject *self UNUSED, PyObject *args)
516{
517 char *expr;
518
519 if (!PyArg_ParseTuple(args, "s", &expr))
520 return NULL;
521
Bram Moolenaara54bf402012-12-05 16:30:07 +0100522 return PyLong_FromLong(
523#ifdef FEAT_MBYTE
524 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
525#else
526 STRLEN(expr)
527#endif
528 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200529}
530
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200531/*
532 * Vim module - Definitions
533 */
534
535static struct PyMethodDef VimMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200536 /* name, function, calling, documentation */
537 {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
538 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
539 {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
540 {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
541 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200542};
543
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200544/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200545 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200546 */
547
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200548static PyTypeObject IterType;
549
550typedef PyObject *(*nextfun)(void **);
551typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200552typedef int (*traversefun)(void *, visitproc, void *);
553typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200554
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200555/* Main purpose of this object is removing the need for do python
556 * initialization (i.e. PyType_Ready and setting type attributes) for a big
557 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200558
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200559typedef struct
560{
561 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200562 void *cur;
563 nextfun next;
564 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200565 traversefun traverse;
566 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200567} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200568
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200569 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200570IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
571 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200572{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200573 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200574
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200575 self = PyObject_NEW(IterObject, &IterType);
576 self->cur = start;
577 self->next = next;
578 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200579 self->traverse = traverse;
580 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200581
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200582 return (PyObject *)(self);
583}
584
585 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200586IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200587{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200588 self->destruct(self->cur);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200589
590 DESTRUCTOR_FINISH(self);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200591}
592
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200593 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200594IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200595{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200596 if (self->traverse != NULL)
597 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200598 else
599 return 0;
600}
601
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200602/* Mac OSX defines clear() somewhere. */
603#ifdef clear
604# undef clear
605#endif
606
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200607 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200608IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200609{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200610 if (self->clear != NULL)
611 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200612 else
613 return 0;
614}
615
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200616 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200617IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200618{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200619 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200620}
621
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200622 static PyObject *
623IterIter(PyObject *self)
624{
625 return self;
626}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200627
Bram Moolenaardb913952012-06-29 12:54:53 +0200628typedef struct pylinkedlist_S {
629 struct pylinkedlist_S *pll_next;
630 struct pylinkedlist_S *pll_prev;
631 PyObject *pll_obj;
632} pylinkedlist_T;
633
634static pylinkedlist_T *lastdict = NULL;
635static pylinkedlist_T *lastlist = NULL;
636
637 static void
638pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
639{
640 if (ref->pll_prev == NULL)
641 {
642 if (ref->pll_next == NULL)
643 {
644 *last = NULL;
645 return;
646 }
647 }
648 else
649 ref->pll_prev->pll_next = ref->pll_next;
650
651 if (ref->pll_next == NULL)
652 *last = ref->pll_prev;
653 else
654 ref->pll_next->pll_prev = ref->pll_prev;
655}
656
657 static void
658pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
659{
660 if (*last == NULL)
661 ref->pll_prev = NULL;
662 else
663 {
664 (*last)->pll_next = ref;
665 ref->pll_prev = *last;
666 }
667 ref->pll_next = NULL;
668 ref->pll_obj = self;
669 *last = ref;
670}
671
672static PyTypeObject DictionaryType;
673
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200674#define DICTKEY_GET_NOTEMPTY(err) \
675 DICTKEY_GET(err) \
676 if (*key == NUL) \
677 { \
678 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
679 return err; \
680 }
681
Bram Moolenaardb913952012-06-29 12:54:53 +0200682typedef struct
683{
684 PyObject_HEAD
685 dict_T *dict;
686 pylinkedlist_T ref;
687} DictionaryObject;
688
689 static PyObject *
690DictionaryNew(dict_T *dict)
691{
692 DictionaryObject *self;
693
694 self = PyObject_NEW(DictionaryObject, &DictionaryType);
695 if (self == NULL)
696 return NULL;
697 self->dict = dict;
698 ++dict->dv_refcount;
699
700 pyll_add((PyObject *)(self), &self->ref, &lastdict);
701
702 return (PyObject *)(self);
703}
704
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200705 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200706DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200707{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200708 pyll_remove(&self->ref, &lastdict);
709 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200710
711 DESTRUCTOR_FINISH(self);
712}
713
Bram Moolenaardb913952012-06-29 12:54:53 +0200714 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200715DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200716{
717 if (val == NULL)
718 {
719 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
720 return -1;
721 }
722
723 if (strcmp(name, "locked") == 0)
724 {
Bram Moolenaard6e39182013-05-21 18:30:34 +0200725 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200726 {
727 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
728 return -1;
729 }
730 else
731 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200732 int istrue = PyObject_IsTrue(val);
733 if (istrue == -1)
734 return -1;
735 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +0200736 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200737 else
Bram Moolenaard6e39182013-05-21 18:30:34 +0200738 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200739 }
740 return 0;
741 }
742 else
743 {
744 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
745 return -1;
746 }
747}
748
749 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200750DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200751{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200752 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +0200753}
754
755 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200756DictionaryItem(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200757{
758 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200759 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200760 DICTKEY_DECL
761
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200762 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200763
Bram Moolenaard6e39182013-05-21 18:30:34 +0200764 di = dict_find(self->dict, key, -1);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200765
Bram Moolenaar696c2112012-09-21 13:43:14 +0200766 DICTKEY_UNREF
767
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200768 if (di == NULL)
769 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200770 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200771 return NULL;
772 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200773
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200774 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200775}
776
777 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200778DictionaryAssItem(DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200779{
780 char_u *key;
781 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200782 dict_T *d = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200783 dictitem_T *di;
784 DICTKEY_DECL
785
786 if (d->dv_lock)
787 {
788 PyErr_SetVim(_("dict is locked"));
789 return -1;
790 }
791
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200792 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200793
794 di = dict_find(d, key, -1);
795
796 if (valObject == NULL)
797 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200798 hashitem_T *hi;
799
Bram Moolenaardb913952012-06-29 12:54:53 +0200800 if (di == NULL)
801 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200802 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200803 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +0200804 return -1;
805 }
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200806 hi = hash_find(&d->dv_hashtab, di->di_key);
Bram Moolenaardb913952012-06-29 12:54:53 +0200807 hash_remove(&d->dv_hashtab, hi);
808 dictitem_free(di);
809 return 0;
810 }
811
812 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200813 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +0200814
815 if (di == NULL)
816 {
817 di = dictitem_alloc(key);
818 if (di == NULL)
819 {
820 PyErr_NoMemory();
821 return -1;
822 }
823 di->di_tv.v_lock = 0;
824
825 if (dict_add(d, di) == FAIL)
826 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200827 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200828 vim_free(di);
829 PyErr_SetVim(_("failed to add key to dictionary"));
830 return -1;
831 }
832 }
833 else
834 clear_tv(&di->di_tv);
835
836 DICTKEY_UNREF
837
838 copy_tv(&tv, &di->di_tv);
839 return 0;
840}
841
842 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200843DictionaryListKeys(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200844{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200845 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200846 long_u todo = dict->dv_hashtab.ht_used;
847 Py_ssize_t i = 0;
848 PyObject *r;
849 hashitem_T *hi;
850
851 r = PyList_New(todo);
852 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
853 {
854 if (!HASHITEM_EMPTY(hi))
855 {
856 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
857 --todo;
858 ++i;
859 }
860 }
861 return r;
862}
863
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200864static PyMappingMethods DictionaryAsMapping = {
865 (lenfunc) DictionaryLength,
866 (binaryfunc) DictionaryItem,
867 (objobjargproc) DictionaryAssItem,
868};
869
Bram Moolenaardb913952012-06-29 12:54:53 +0200870static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200871 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
872 { NULL, NULL, 0, NULL }
Bram Moolenaardb913952012-06-29 12:54:53 +0200873};
874
875static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200876static PySequenceMethods ListAsSeq;
877static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +0200878
879typedef struct
880{
881 PyObject_HEAD
882 list_T *list;
883 pylinkedlist_T ref;
884} ListObject;
885
886 static PyObject *
887ListNew(list_T *list)
888{
889 ListObject *self;
890
891 self = PyObject_NEW(ListObject, &ListType);
892 if (self == NULL)
893 return NULL;
894 self->list = list;
895 ++list->lv_refcount;
896
897 pyll_add((PyObject *)(self), &self->ref, &lastlist);
898
899 return (PyObject *)(self);
900}
901
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200902 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200903ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200904{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200905 pyll_remove(&self->ref, &lastlist);
906 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200907
908 DESTRUCTOR_FINISH(self);
909}
910
Bram Moolenaardb913952012-06-29 12:54:53 +0200911 static int
912list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
913{
914 Py_ssize_t i;
915 Py_ssize_t lsize = PySequence_Size(obj);
916 PyObject *litem;
917 listitem_T *li;
918
919 for(i=0; i<lsize; i++)
920 {
921 li = listitem_alloc();
922 if (li == NULL)
923 {
924 PyErr_NoMemory();
925 return -1;
926 }
927 li->li_tv.v_lock = 0;
928
929 litem = PySequence_GetItem(obj, i);
930 if (litem == NULL)
931 return -1;
932 if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
933 return -1;
934
935 list_append(l, li);
936 }
937 return 0;
938}
939
Bram Moolenaardb913952012-06-29 12:54:53 +0200940 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200941ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200942{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200943 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +0200944}
945
946 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200947ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +0200948{
949 listitem_T *li;
950
Bram Moolenaard6e39182013-05-21 18:30:34 +0200951 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +0200952 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200953 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +0200954 return NULL;
955 }
Bram Moolenaard6e39182013-05-21 18:30:34 +0200956 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +0200957 if (li == NULL)
958 {
959 PyErr_SetVim(_("internal error: failed to get vim list item"));
960 return NULL;
961 }
962 return ConvertToPyObject(&li->li_tv);
963}
964
965#define PROC_RANGE \
966 if (last < 0) {\
967 if (last < -size) \
968 last = 0; \
969 else \
970 last += size; \
971 } \
972 if (first < 0) \
973 first = 0; \
974 if (first > size) \
975 first = size; \
976 if (last > size) \
977 last = size;
978
979 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200980ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +0200981{
982 PyInt i;
983 PyInt size = ListLength(self);
984 PyInt n;
985 PyObject *list;
986 int reversed = 0;
987
988 PROC_RANGE
989 if (first >= last)
990 first = last;
991
992 n = last-first;
993 list = PyList_New(n);
994 if (list == NULL)
995 return NULL;
996
997 for (i = 0; i < n; ++i)
998 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +0200999 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02001000 if (item == NULL)
1001 {
1002 Py_DECREF(list);
1003 return NULL;
1004 }
1005
1006 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1007 {
1008 Py_DECREF(item);
1009 Py_DECREF(list);
1010 return NULL;
1011 }
1012 }
1013
1014 return list;
1015}
1016
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001017typedef struct
1018{
1019 listwatch_T lw;
1020 list_T *list;
1021} listiterinfo_T;
1022
1023 static void
1024ListIterDestruct(listiterinfo_T *lii)
1025{
1026 list_rem_watch(lii->list, &lii->lw);
1027 PyMem_Free(lii);
1028}
1029
1030 static PyObject *
1031ListIterNext(listiterinfo_T **lii)
1032{
1033 PyObject *r;
1034
1035 if (!((*lii)->lw.lw_item))
1036 return NULL;
1037
1038 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1039 return NULL;
1040
1041 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1042
1043 return r;
1044}
1045
1046 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001047ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001048{
1049 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001050 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001051
1052 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1053 {
1054 PyErr_NoMemory();
1055 return NULL;
1056 }
1057
1058 list_add_watch(l, &lii->lw);
1059 lii->lw.lw_item = l->lv_first;
1060 lii->list = l;
1061
1062 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001063 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
1064 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001065}
1066
Bram Moolenaardb913952012-06-29 12:54:53 +02001067 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001068ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001069{
1070 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001071 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001072 listitem_T *li;
1073 Py_ssize_t length = ListLength(self);
1074
1075 if (l->lv_lock)
1076 {
1077 PyErr_SetVim(_("list is locked"));
1078 return -1;
1079 }
1080 if (index>length || (index==length && obj==NULL))
1081 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001082 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001083 return -1;
1084 }
1085
1086 if (obj == NULL)
1087 {
1088 li = list_find(l, (long) index);
1089 list_remove(l, li, li);
1090 clear_tv(&li->li_tv);
1091 vim_free(li);
1092 return 0;
1093 }
1094
1095 if (ConvertFromPyObject(obj, &tv) == -1)
1096 return -1;
1097
1098 if (index == length)
1099 {
1100 if (list_append_tv(l, &tv) == FAIL)
1101 {
1102 PyErr_SetVim(_("Failed to add item to list"));
1103 return -1;
1104 }
1105 }
1106 else
1107 {
1108 li = list_find(l, (long) index);
1109 clear_tv(&li->li_tv);
1110 copy_tv(&tv, &li->li_tv);
1111 }
1112 return 0;
1113}
1114
1115 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001116ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001117{
1118 PyInt size = ListLength(self);
1119 Py_ssize_t i;
1120 Py_ssize_t lsize;
1121 PyObject *litem;
1122 listitem_T *li;
1123 listitem_T *next;
1124 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001125 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001126
1127 if (l->lv_lock)
1128 {
1129 PyErr_SetVim(_("list is locked"));
1130 return -1;
1131 }
1132
1133 PROC_RANGE
1134
1135 if (first == size)
1136 li = NULL;
1137 else
1138 {
1139 li = list_find(l, (long) first);
1140 if (li == NULL)
1141 {
1142 PyErr_SetVim(_("internal error: no vim list item"));
1143 return -1;
1144 }
1145 if (last > first)
1146 {
1147 i = last - first;
1148 while (i-- && li != NULL)
1149 {
1150 next = li->li_next;
1151 listitem_remove(l, li);
1152 li = next;
1153 }
1154 }
1155 }
1156
1157 if (obj == NULL)
1158 return 0;
1159
1160 if (!PyList_Check(obj))
1161 {
1162 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1163 return -1;
1164 }
1165
1166 lsize = PyList_Size(obj);
1167
1168 for(i=0; i<lsize; i++)
1169 {
1170 litem = PyList_GetItem(obj, i);
1171 if (litem == NULL)
1172 return -1;
1173 if (ConvertFromPyObject(litem, &v) == -1)
1174 return -1;
1175 if (list_insert_tv(l, &v, li) == FAIL)
1176 {
1177 PyErr_SetVim(_("internal error: failed to add item to list"));
1178 return -1;
1179 }
1180 }
1181 return 0;
1182}
1183
1184 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001185ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001186{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001187 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001188 PyObject *lookup_dict;
1189
1190 if (l->lv_lock)
1191 {
1192 PyErr_SetVim(_("list is locked"));
1193 return NULL;
1194 }
1195
1196 if (!PySequence_Check(obj))
1197 {
1198 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1199 return NULL;
1200 }
1201
1202 lookup_dict = PyDict_New();
1203 if (list_py_concat(l, obj, lookup_dict) == -1)
1204 {
1205 Py_DECREF(lookup_dict);
1206 return NULL;
1207 }
1208 Py_DECREF(lookup_dict);
1209
1210 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02001211 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02001212}
1213
Bram Moolenaar66b79852012-09-21 14:00:35 +02001214 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001215ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001216{
1217 if (val == NULL)
1218 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001219 PyErr_SetString(PyExc_AttributeError,
1220 _("cannot delete vim.dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001221 return -1;
1222 }
1223
1224 if (strcmp(name, "locked") == 0)
1225 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001226 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001227 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001228 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001229 return -1;
1230 }
1231 else
1232 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001233 int istrue = PyObject_IsTrue(val);
1234 if (istrue == -1)
1235 return -1;
1236 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001237 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001238 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001239 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001240 }
1241 return 0;
1242 }
1243 else
1244 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001245 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001246 return -1;
1247 }
1248}
1249
Bram Moolenaardb913952012-06-29 12:54:53 +02001250static struct PyMethodDef ListMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001251 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1252 { NULL, NULL, 0, NULL }
Bram Moolenaardb913952012-06-29 12:54:53 +02001253};
1254
1255typedef struct
1256{
1257 PyObject_HEAD
1258 char_u *name;
1259} FunctionObject;
1260
1261static PyTypeObject FunctionType;
1262
1263 static PyObject *
1264FunctionNew(char_u *name)
1265{
1266 FunctionObject *self;
1267
1268 self = PyObject_NEW(FunctionObject, &FunctionType);
1269 if (self == NULL)
1270 return NULL;
1271 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1272 if (self->name == NULL)
1273 {
1274 PyErr_NoMemory();
1275 return NULL;
1276 }
1277 STRCPY(self->name, name);
1278 func_ref(name);
1279 return (PyObject *)(self);
1280}
1281
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001282 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001283FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001284{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001285 func_unref(self->name);
1286 PyMem_Free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001287
1288 DESTRUCTOR_FINISH(self);
1289}
1290
Bram Moolenaardb913952012-06-29 12:54:53 +02001291 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001292FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02001293{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001294 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02001295 typval_T args;
1296 typval_T selfdicttv;
1297 typval_T rettv;
1298 dict_T *selfdict = NULL;
1299 PyObject *selfdictObject;
1300 PyObject *result;
1301 int error;
1302
1303 if (ConvertFromPyObject(argsObject, &args) == -1)
1304 return NULL;
1305
1306 if (kwargs != NULL)
1307 {
1308 selfdictObject = PyDict_GetItemString(kwargs, "self");
1309 if (selfdictObject != NULL)
1310 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001311 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001312 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001313 PyErr_SetString(PyExc_TypeError,
1314 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001315 clear_tv(&args);
1316 return NULL;
1317 }
1318 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
1319 return NULL;
1320 selfdict = selfdicttv.vval.v_dict;
1321 }
1322 }
1323
Bram Moolenaar71700b82013-05-15 17:49:05 +02001324 Py_BEGIN_ALLOW_THREADS
1325 Python_Lock_Vim();
1326
Bram Moolenaardb913952012-06-29 12:54:53 +02001327 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02001328
1329 Python_Release_Vim();
1330 Py_END_ALLOW_THREADS
1331
Bram Moolenaardb913952012-06-29 12:54:53 +02001332 if (error != OK)
1333 {
1334 result = NULL;
1335 PyErr_SetVim(_("failed to run function"));
1336 }
1337 else
1338 result = ConvertToPyObject(&rettv);
1339
1340 /* FIXME Check what should really be cleared. */
1341 clear_tv(&args);
1342 clear_tv(&rettv);
1343 /*
1344 * if (selfdict!=NULL)
1345 * clear_tv(selfdicttv);
1346 */
1347
1348 return result;
1349}
1350
1351static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001352 {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1353 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001354};
1355
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001356/*
1357 * Options object
1358 */
1359
1360static PyTypeObject OptionsType;
1361
1362typedef int (*checkfun)(void *);
1363
1364typedef struct
1365{
1366 PyObject_HEAD
1367 int opt_type;
1368 void *from;
1369 checkfun Check;
1370 PyObject *fromObj;
1371} OptionsObject;
1372
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001373 static int
1374dummy_check(void *arg UNUSED)
1375{
1376 return 0;
1377}
1378
1379 static PyObject *
1380OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1381{
1382 OptionsObject *self;
1383
1384 self = PyObject_NEW(OptionsObject, &OptionsType);
1385 if (self == NULL)
1386 return NULL;
1387
1388 self->opt_type = opt_type;
1389 self->from = from;
1390 self->Check = Check;
1391 self->fromObj = fromObj;
1392 if (fromObj)
1393 Py_INCREF(fromObj);
1394
1395 return (PyObject *)(self);
1396}
1397
1398 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001399OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001400{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001401 if (self->fromObj)
1402 Py_DECREF(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001403 DESTRUCTOR_FINISH(self);
1404}
1405
1406 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001407OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001408{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001409 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001410 return 0;
1411}
1412
1413 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001414OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001415{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001416 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001417 return 0;
1418}
1419
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001420 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001421OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001422{
1423 char_u *key;
1424 int flags;
1425 long numval;
1426 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001427 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001428
Bram Moolenaard6e39182013-05-21 18:30:34 +02001429 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001430 return NULL;
1431
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001432 DICTKEY_GET_NOTEMPTY(NULL)
1433
1434 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001435 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001436
1437 DICTKEY_UNREF
1438
1439 if (flags == 0)
1440 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001441 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001442 return NULL;
1443 }
1444
1445 if (flags & SOPT_UNSET)
1446 {
1447 Py_INCREF(Py_None);
1448 return Py_None;
1449 }
1450 else if (flags & SOPT_BOOL)
1451 {
1452 PyObject *r;
1453 r = numval ? Py_True : Py_False;
1454 Py_INCREF(r);
1455 return r;
1456 }
1457 else if (flags & SOPT_NUM)
1458 return PyInt_FromLong(numval);
1459 else if (flags & SOPT_STRING)
1460 {
1461 if (stringval)
1462 return PyBytes_FromString((char *) stringval);
1463 else
1464 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001465 PyErr_SetString(PyExc_RuntimeError,
1466 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001467 return NULL;
1468 }
1469 }
1470 else
1471 {
1472 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1473 return NULL;
1474 }
1475}
1476
1477 static int
1478set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1479 char_u *key;
1480 int numval;
1481 char_u *stringval;
1482 int opt_flags;
1483 int opt_type;
1484 void *from;
1485{
1486 win_T *save_curwin;
1487 tabpage_T *save_curtab;
Bram Moolenaar105bc352013-05-17 16:03:57 +02001488 buf_T *save_curbuf;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001489 int r = 0;
1490
1491 switch (opt_type)
1492 {
1493 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001494 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
1495 win_find_tabpage((win_T *)from)) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001496 {
1497 PyErr_SetVim("Problem while switching windows.");
1498 return -1;
1499 }
1500 set_option_value(key, numval, stringval, opt_flags);
1501 restore_win(save_curwin, save_curtab);
1502 break;
1503 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001504 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001505 set_option_value(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02001506 restore_buffer(save_curbuf);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001507 break;
1508 case SREQ_GLOBAL:
1509 set_option_value(key, numval, stringval, opt_flags);
1510 break;
1511 }
1512 return r;
1513}
1514
1515 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001516OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001517{
1518 char_u *key;
1519 int flags;
1520 int opt_flags;
1521 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001522 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001523
Bram Moolenaard6e39182013-05-21 18:30:34 +02001524 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001525 return -1;
1526
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001527 DICTKEY_GET_NOTEMPTY(-1)
1528
1529 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001530 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001531
1532 DICTKEY_UNREF
1533
1534 if (flags == 0)
1535 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001536 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001537 return -1;
1538 }
1539
1540 if (valObject == NULL)
1541 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001542 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001543 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001544 PyErr_SetString(PyExc_ValueError,
1545 _("unable to unset global option"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001546 return -1;
1547 }
1548 else if (!(flags & SOPT_GLOBAL))
1549 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001550 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
1551 "without global value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001552 return -1;
1553 }
1554 else
1555 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001556 unset_global_local_option(key, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001557 return 0;
1558 }
1559 }
1560
Bram Moolenaard6e39182013-05-21 18:30:34 +02001561 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001562
1563 if (flags & SOPT_BOOL)
1564 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001565 int istrue = PyObject_IsTrue(valObject);
1566 if (istrue == -1)
1567 return -1;
1568 r = set_option_value_for(key, istrue, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001569 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001570 }
1571 else if (flags & SOPT_NUM)
1572 {
1573 int val;
1574
1575#if PY_MAJOR_VERSION < 3
1576 if (PyInt_Check(valObject))
1577 val = PyInt_AsLong(valObject);
1578 else
1579#endif
1580 if (PyLong_Check(valObject))
1581 val = PyLong_AsLong(valObject);
1582 else
1583 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001584 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001585 return -1;
1586 }
1587
1588 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001589 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001590 }
1591 else
1592 {
1593 char_u *val;
1594 if (PyBytes_Check(valObject))
1595 {
1596
1597 if (PyString_AsStringAndSize(valObject, (char **) &val, NULL) == -1)
1598 return -1;
1599 if (val == NULL)
1600 return -1;
1601
1602 val = vim_strsave(val);
1603 }
1604 else if (PyUnicode_Check(valObject))
1605 {
1606 PyObject *bytes;
1607
1608 bytes = PyUnicode_AsEncodedString(valObject, (char *)ENC_OPT, NULL);
1609 if (bytes == NULL)
1610 return -1;
1611
1612 if(PyString_AsStringAndSize(bytes, (char **) &val, NULL) == -1)
1613 return -1;
1614 if (val == NULL)
1615 return -1;
1616
1617 val = vim_strsave(val);
1618 Py_XDECREF(bytes);
1619 }
1620 else
1621 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001622 PyErr_SetString(PyExc_TypeError, _("object must be string"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001623 return -1;
1624 }
1625
1626 r = set_option_value_for(key, 0, val, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001627 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001628 vim_free(val);
1629 }
1630
1631 return r;
1632}
1633
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001634static PyMappingMethods OptionsAsMapping = {
1635 (lenfunc) NULL,
1636 (binaryfunc) OptionsItem,
1637 (objobjargproc) OptionsAssItem,
1638};
1639
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001640/* Tabpage object
1641 */
1642
1643typedef struct
1644{
1645 PyObject_HEAD
1646 tabpage_T *tab;
1647} TabPageObject;
1648
1649static PyObject *WinListNew(TabPageObject *tabObject);
1650
1651static PyTypeObject TabPageType;
1652
1653 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001654CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001655{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001656 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001657 {
1658 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1659 return -1;
1660 }
1661
1662 return 0;
1663}
1664
1665 static PyObject *
1666TabPageNew(tabpage_T *tab)
1667{
1668 TabPageObject *self;
1669
1670 if (TAB_PYTHON_REF(tab))
1671 {
1672 self = TAB_PYTHON_REF(tab);
1673 Py_INCREF(self);
1674 }
1675 else
1676 {
1677 self = PyObject_NEW(TabPageObject, &TabPageType);
1678 if (self == NULL)
1679 return NULL;
1680 self->tab = tab;
1681 TAB_PYTHON_REF(tab) = self;
1682 }
1683
1684 return (PyObject *)(self);
1685}
1686
1687 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001688TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001689{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001690 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
1691 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001692
1693 DESTRUCTOR_FINISH(self);
1694}
1695
1696 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001697TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001698{
1699 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001700 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001701 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001702 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001703 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001704 return DictionaryNew(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001705 else if (strcmp(name, "window") == 0)
1706 {
1707 /* For current tab window.c does not bother to set or update tp_curwin
1708 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001709 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001710 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001711 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001712 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001713 }
1714 return NULL;
1715}
1716
1717 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001718TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001719{
1720 static char repr[100];
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001721
Bram Moolenaard6e39182013-05-21 18:30:34 +02001722 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001723 {
1724 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
1725 return PyString_FromString(repr);
1726 }
1727 else
1728 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001729 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001730
1731 if (t == 0)
1732 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
1733 (self));
1734 else
1735 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
1736
1737 return PyString_FromString(repr);
1738 }
1739}
1740
1741static struct PyMethodDef TabPageMethods[] = {
1742 /* name, function, calling, documentation */
1743 { NULL, NULL, 0, NULL }
1744};
1745
1746/*
1747 * Window list object
1748 */
1749
1750static PyTypeObject TabListType;
1751static PySequenceMethods TabListAsSeq;
1752
1753typedef struct
1754{
1755 PyObject_HEAD
1756} TabListObject;
1757
1758 static PyInt
1759TabListLength(PyObject *self UNUSED)
1760{
1761 tabpage_T *tp = first_tabpage;
1762 PyInt n = 0;
1763
1764 while (tp != NULL)
1765 {
1766 ++n;
1767 tp = tp->tp_next;
1768 }
1769
1770 return n;
1771}
1772
1773 static PyObject *
1774TabListItem(PyObject *self UNUSED, PyInt n)
1775{
1776 tabpage_T *tp;
1777
1778 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
1779 if (n == 0)
1780 return TabPageNew(tp);
1781
1782 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
1783 return NULL;
1784}
1785
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001786/* Window object
1787 */
1788
1789typedef struct
1790{
1791 PyObject_HEAD
1792 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001793 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001794} WindowObject;
1795
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001796static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001797
1798 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001799CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001800{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001801 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001802 {
1803 PyErr_SetVim(_("attempt to refer to deleted window"));
1804 return -1;
1805 }
1806
1807 return 0;
1808}
1809
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001810 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001811WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02001812{
1813 /* We need to handle deletion of windows underneath us.
1814 * If we add a "w_python*_ref" field to the win_T structure,
1815 * then we can get at it in win_free() in vim. We then
1816 * need to create only ONE Python object per window - if
1817 * we try to create a second, just INCREF the existing one
1818 * and return it. The (single) Python object referring to
1819 * the window is stored in "w_python*_ref".
1820 * On a win_free() we set the Python object's win_T* field
1821 * to an invalid value. We trap all uses of a window
1822 * object, and reject them if the win_T* field is invalid.
1823 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001824 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02001825 * w_python_ref and w_python3_ref fields respectively.
1826 */
1827
1828 WindowObject *self;
1829
1830 if (WIN_PYTHON_REF(win))
1831 {
1832 self = WIN_PYTHON_REF(win);
1833 Py_INCREF(self);
1834 }
1835 else
1836 {
1837 self = PyObject_NEW(WindowObject, &WindowType);
1838 if (self == NULL)
1839 return NULL;
1840 self->win = win;
1841 WIN_PYTHON_REF(win) = self;
1842 }
1843
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001844 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
1845
Bram Moolenaar971db462013-05-12 18:44:48 +02001846 return (PyObject *)(self);
1847}
1848
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001849 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001850WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001851{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001852 if (self->win && self->win != INVALID_WINDOW_VALUE)
1853 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001854
Bram Moolenaard6e39182013-05-21 18:30:34 +02001855 Py_DECREF(((PyObject *)(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001856
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001857 DESTRUCTOR_FINISH(self);
1858}
1859
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001860 static win_T *
1861get_firstwin(TabPageObject *tabObject)
1862{
1863 if (tabObject)
1864 {
1865 if (CheckTabPage(tabObject))
1866 return NULL;
1867 /* For current tab window.c does not bother to set or update tp_firstwin
1868 */
1869 else if (tabObject->tab == curtab)
1870 return firstwin;
1871 else
1872 return tabObject->tab->tp_firstwin;
1873 }
1874 else
1875 return firstwin;
1876}
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001877 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001878WindowTraverse(WindowObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001879{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001880 Py_VISIT(((PyObject *)(self->tabObject)));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001881 return 0;
1882}
1883
1884 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001885WindowClear(WindowObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001886{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001887 Py_CLEAR(self->tabObject);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001888 return 0;
1889}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001890
Bram Moolenaar971db462013-05-12 18:44:48 +02001891 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001892WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001893{
1894 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001895 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001896 else if (strcmp(name, "cursor") == 0)
1897 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001898 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001899
1900 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1901 }
1902 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001903 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001904#ifdef FEAT_WINDOWS
1905 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001906 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001907#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001908#ifdef FEAT_VERTSPLIT
1909 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001910 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02001911 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001912 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001913#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02001914 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001915 return DictionaryNew(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001916 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001917 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
1918 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02001919 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001920 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001921 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001922 return NULL;
1923 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001924 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001925 }
1926 else if (strcmp(name, "tabpage") == 0)
1927 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001928 Py_INCREF(self->tabObject);
1929 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001930 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001931 else if (strcmp(name,"__members__") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001932 return Py_BuildValue("[sssssssss]", "buffer", "cursor", "height",
1933 "vars", "options", "number", "row", "col", "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001934 else
1935 return NULL;
1936}
1937
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001938 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001939WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001940{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001941 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001942 return -1;
1943
1944 if (strcmp(name, "buffer") == 0)
1945 {
1946 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1947 return -1;
1948 }
1949 else if (strcmp(name, "cursor") == 0)
1950 {
1951 long lnum;
1952 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001953
1954 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1955 return -1;
1956
Bram Moolenaard6e39182013-05-21 18:30:34 +02001957 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001958 {
1959 PyErr_SetVim(_("cursor position outside buffer"));
1960 return -1;
1961 }
1962
1963 /* Check for keyboard interrupts */
1964 if (VimErrorCheck())
1965 return -1;
1966
Bram Moolenaard6e39182013-05-21 18:30:34 +02001967 self->win->w_cursor.lnum = lnum;
1968 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001969#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02001970 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001971#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001972 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001973 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001974
Bram Moolenaar03a807a2011-07-07 15:08:58 +02001975 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001976 return 0;
1977 }
1978 else if (strcmp(name, "height") == 0)
1979 {
1980 int height;
1981 win_T *savewin;
1982
1983 if (!PyArg_Parse(val, "i", &height))
1984 return -1;
1985
1986#ifdef FEAT_GUI
1987 need_mouse_correct = TRUE;
1988#endif
1989 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001990 curwin = self->win;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001991 win_setheight(height);
1992 curwin = savewin;
1993
1994 /* Check for keyboard interrupts */
1995 if (VimErrorCheck())
1996 return -1;
1997
1998 return 0;
1999 }
2000#ifdef FEAT_VERTSPLIT
2001 else if (strcmp(name, "width") == 0)
2002 {
2003 int width;
2004 win_T *savewin;
2005
2006 if (!PyArg_Parse(val, "i", &width))
2007 return -1;
2008
2009#ifdef FEAT_GUI
2010 need_mouse_correct = TRUE;
2011#endif
2012 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002013 curwin = self->win;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002014 win_setwidth(width);
2015 curwin = savewin;
2016
2017 /* Check for keyboard interrupts */
2018 if (VimErrorCheck())
2019 return -1;
2020
2021 return 0;
2022 }
2023#endif
2024 else
2025 {
2026 PyErr_SetString(PyExc_AttributeError, name);
2027 return -1;
2028 }
2029}
2030
2031 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002032WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002033{
2034 static char repr[100];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002035
Bram Moolenaard6e39182013-05-21 18:30:34 +02002036 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002037 {
2038 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2039 return PyString_FromString(repr);
2040 }
2041 else
2042 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002043 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002044
Bram Moolenaar6d216452013-05-12 19:00:41 +02002045 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002046 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2047 (self));
2048 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02002049 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002050
2051 return PyString_FromString(repr);
2052 }
2053}
2054
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002055static struct PyMethodDef WindowMethods[] = {
2056 /* name, function, calling, documentation */
2057 { NULL, NULL, 0, NULL }
2058};
2059
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002060/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002061 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002062 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002063
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002064static PyTypeObject WinListType;
2065static PySequenceMethods WinListAsSeq;
2066
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002067typedef struct
2068{
2069 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002070 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002071} WinListObject;
2072
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002073 static PyObject *
2074WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002075{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002076 WinListObject *self;
2077
2078 self = PyObject_NEW(WinListObject, &WinListType);
2079 self->tabObject = tabObject;
2080 Py_INCREF(tabObject);
2081
2082 return (PyObject *)(self);
2083}
2084
2085 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002086WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002087{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002088 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002089
2090 if (tabObject)
2091 Py_DECREF((PyObject *)(tabObject));
2092
2093 DESTRUCTOR_FINISH(self);
2094}
2095
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002096 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002097WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002098{
2099 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002100 PyInt n = 0;
2101
Bram Moolenaard6e39182013-05-21 18:30:34 +02002102 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002103 return -1;
2104
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002105 while (w != NULL)
2106 {
2107 ++n;
2108 w = W_NEXT(w);
2109 }
2110
2111 return n;
2112}
2113
2114 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002115WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002116{
2117 win_T *w;
2118
Bram Moolenaard6e39182013-05-21 18:30:34 +02002119 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002120 return NULL;
2121
2122 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002123 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002124 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002125
2126 PyErr_SetString(PyExc_IndexError, _("no such window"));
2127 return NULL;
2128}
2129
2130/* Convert a Python string into a Vim line.
2131 *
2132 * The result is in allocated memory. All internal nulls are replaced by
2133 * newline characters. It is an error for the string to contain newline
2134 * characters.
2135 *
2136 * On errors, the Python exception data is set, and NULL is returned.
2137 */
2138 static char *
2139StringToLine(PyObject *obj)
2140{
2141 const char *str;
2142 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002143 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002144 PyInt len;
2145 PyInt i;
2146 char *p;
2147
2148 if (obj == NULL || !PyString_Check(obj))
2149 {
2150 PyErr_BadArgument();
2151 return NULL;
2152 }
2153
Bram Moolenaar19e60942011-06-19 00:27:51 +02002154 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2155 str = PyString_AsString(bytes);
2156 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002157
2158 /*
2159 * Error checking: String must not contain newlines, as we
2160 * are replacing a single line, and we must replace it with
2161 * a single line.
2162 * A trailing newline is removed, so that append(f.readlines()) works.
2163 */
2164 p = memchr(str, '\n', len);
2165 if (p != NULL)
2166 {
2167 if (p == str + len - 1)
2168 --len;
2169 else
2170 {
2171 PyErr_SetVim(_("string cannot contain newlines"));
2172 return NULL;
2173 }
2174 }
2175
2176 /* Create a copy of the string, with internal nulls replaced by
2177 * newline characters, as is the vim convention.
2178 */
2179 save = (char *)alloc((unsigned)(len+1));
2180 if (save == NULL)
2181 {
2182 PyErr_NoMemory();
2183 return NULL;
2184 }
2185
2186 for (i = 0; i < len; ++i)
2187 {
2188 if (str[i] == '\0')
2189 save[i] = '\n';
2190 else
2191 save[i] = str[i];
2192 }
2193
2194 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002195 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002196
2197 return save;
2198}
2199
2200/* Get a line from the specified buffer. The line number is
2201 * in Vim format (1-based). The line is returned as a Python
2202 * string object.
2203 */
2204 static PyObject *
2205GetBufferLine(buf_T *buf, PyInt n)
2206{
2207 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2208}
2209
2210
2211/* Get a list of lines from the specified buffer. The line numbers
2212 * are in Vim format (1-based). The range is from lo up to, but not
2213 * including, hi. The list is returned as a Python list of string objects.
2214 */
2215 static PyObject *
2216GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2217{
2218 PyInt i;
2219 PyInt n = hi - lo;
2220 PyObject *list = PyList_New(n);
2221
2222 if (list == NULL)
2223 return NULL;
2224
2225 for (i = 0; i < n; ++i)
2226 {
2227 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2228
2229 /* Error check - was the Python string creation OK? */
2230 if (str == NULL)
2231 {
2232 Py_DECREF(list);
2233 return NULL;
2234 }
2235
2236 /* Set the list item */
2237 if (PyList_SetItem(list, i, str))
2238 {
2239 Py_DECREF(str);
2240 Py_DECREF(list);
2241 return NULL;
2242 }
2243 }
2244
2245 /* The ownership of the Python list is passed to the caller (ie,
2246 * the caller should Py_DECREF() the object when it is finished
2247 * with it).
2248 */
2249
2250 return list;
2251}
2252
2253/*
2254 * Check if deleting lines made the cursor position invalid.
2255 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2256 * deleted).
2257 */
2258 static void
2259py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2260{
2261 if (curwin->w_cursor.lnum >= lo)
2262 {
2263 /* Adjust the cursor position if it's in/after the changed
2264 * lines. */
2265 if (curwin->w_cursor.lnum >= hi)
2266 {
2267 curwin->w_cursor.lnum += extra;
2268 check_cursor_col();
2269 }
2270 else if (extra < 0)
2271 {
2272 curwin->w_cursor.lnum = lo;
2273 check_cursor();
2274 }
2275 else
2276 check_cursor_col();
2277 changed_cline_bef_curs();
2278 }
2279 invalidate_botline();
2280}
2281
Bram Moolenaar19e60942011-06-19 00:27:51 +02002282/*
2283 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002284 * in Vim format (1-based). The replacement line is given as
2285 * a Python string object. The object is checked for validity
2286 * and correct format. Errors are returned as a value of FAIL.
2287 * The return value is OK on success.
2288 * If OK is returned and len_change is not NULL, *len_change
2289 * is set to the change in the buffer length.
2290 */
2291 static int
2292SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2293{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002294 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002295 * There are three cases:
2296 * 1. NULL, or None - this is a deletion.
2297 * 2. A string - this is a replacement.
2298 * 3. Anything else - this is an error.
2299 */
2300 if (line == Py_None || line == NULL)
2301 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002302 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002303
2304 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002305 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002306
2307 if (u_savedel((linenr_T)n, 1L) == FAIL)
2308 PyErr_SetVim(_("cannot save undo information"));
2309 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2310 PyErr_SetVim(_("cannot delete line"));
2311 else
2312 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002313 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002314 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2315 deleted_lines_mark((linenr_T)n, 1L);
2316 }
2317
Bram Moolenaar105bc352013-05-17 16:03:57 +02002318 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002319
2320 if (PyErr_Occurred() || VimErrorCheck())
2321 return FAIL;
2322
2323 if (len_change)
2324 *len_change = -1;
2325
2326 return OK;
2327 }
2328 else if (PyString_Check(line))
2329 {
2330 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002331 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002332
2333 if (save == NULL)
2334 return FAIL;
2335
2336 /* We do not need to free "save" if ml_replace() consumes it. */
2337 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002338 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002339
2340 if (u_savesub((linenr_T)n) == FAIL)
2341 {
2342 PyErr_SetVim(_("cannot save undo information"));
2343 vim_free(save);
2344 }
2345 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2346 {
2347 PyErr_SetVim(_("cannot replace line"));
2348 vim_free(save);
2349 }
2350 else
2351 changed_bytes((linenr_T)n, 0);
2352
Bram Moolenaar105bc352013-05-17 16:03:57 +02002353 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002354
2355 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02002356 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002357 check_cursor_col();
2358
2359 if (PyErr_Occurred() || VimErrorCheck())
2360 return FAIL;
2361
2362 if (len_change)
2363 *len_change = 0;
2364
2365 return OK;
2366 }
2367 else
2368 {
2369 PyErr_BadArgument();
2370 return FAIL;
2371 }
2372}
2373
Bram Moolenaar19e60942011-06-19 00:27:51 +02002374/* Replace a range of lines in the specified buffer. The line numbers are in
2375 * Vim format (1-based). The range is from lo up to, but not including, hi.
2376 * The replacement lines are given as a Python list of string objects. The
2377 * list is checked for validity and correct format. Errors are returned as a
2378 * value of FAIL. The return value is OK on success.
2379 * If OK is returned and len_change is not NULL, *len_change
2380 * is set to the change in the buffer length.
2381 */
2382 static int
2383SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2384{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002385 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002386 * There are three cases:
2387 * 1. NULL, or None - this is a deletion.
2388 * 2. A list - this is a replacement.
2389 * 3. Anything else - this is an error.
2390 */
2391 if (list == Py_None || list == NULL)
2392 {
2393 PyInt i;
2394 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002395 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002396
2397 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002398 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002399
2400 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2401 PyErr_SetVim(_("cannot save undo information"));
2402 else
2403 {
2404 for (i = 0; i < n; ++i)
2405 {
2406 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2407 {
2408 PyErr_SetVim(_("cannot delete line"));
2409 break;
2410 }
2411 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02002412 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002413 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2414 deleted_lines_mark((linenr_T)lo, (long)i);
2415 }
2416
Bram Moolenaar105bc352013-05-17 16:03:57 +02002417 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002418
2419 if (PyErr_Occurred() || VimErrorCheck())
2420 return FAIL;
2421
2422 if (len_change)
2423 *len_change = -n;
2424
2425 return OK;
2426 }
2427 else if (PyList_Check(list))
2428 {
2429 PyInt i;
2430 PyInt new_len = PyList_Size(list);
2431 PyInt old_len = hi - lo;
2432 PyInt extra = 0; /* lines added to text, can be negative */
2433 char **array;
2434 buf_T *savebuf;
2435
2436 if (new_len == 0) /* avoid allocating zero bytes */
2437 array = NULL;
2438 else
2439 {
2440 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2441 if (array == NULL)
2442 {
2443 PyErr_NoMemory();
2444 return FAIL;
2445 }
2446 }
2447
2448 for (i = 0; i < new_len; ++i)
2449 {
2450 PyObject *line = PyList_GetItem(list, i);
2451
2452 array[i] = StringToLine(line);
2453 if (array[i] == NULL)
2454 {
2455 while (i)
2456 vim_free(array[--i]);
2457 vim_free(array);
2458 return FAIL;
2459 }
2460 }
2461
Bram Moolenaar19e60942011-06-19 00:27:51 +02002462 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002463
2464 // START of region without "return". Must call restore_buffer()!
2465 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002466
2467 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2468 PyErr_SetVim(_("cannot save undo information"));
2469
2470 /* If the size of the range is reducing (ie, new_len < old_len) we
2471 * need to delete some old_len. We do this at the start, by
2472 * repeatedly deleting line "lo".
2473 */
2474 if (!PyErr_Occurred())
2475 {
2476 for (i = 0; i < old_len - new_len; ++i)
2477 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2478 {
2479 PyErr_SetVim(_("cannot delete line"));
2480 break;
2481 }
2482 extra -= i;
2483 }
2484
2485 /* For as long as possible, replace the existing old_len with the
2486 * new old_len. This is a more efficient operation, as it requires
2487 * less memory allocation and freeing.
2488 */
2489 if (!PyErr_Occurred())
2490 {
2491 for (i = 0; i < old_len && i < new_len; ++i)
2492 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2493 == FAIL)
2494 {
2495 PyErr_SetVim(_("cannot replace line"));
2496 break;
2497 }
2498 }
2499 else
2500 i = 0;
2501
2502 /* Now we may need to insert the remaining new old_len. If we do, we
2503 * must free the strings as we finish with them (we can't pass the
2504 * responsibility to vim in this case).
2505 */
2506 if (!PyErr_Occurred())
2507 {
2508 while (i < new_len)
2509 {
2510 if (ml_append((linenr_T)(lo + i - 1),
2511 (char_u *)array[i], 0, FALSE) == FAIL)
2512 {
2513 PyErr_SetVim(_("cannot insert line"));
2514 break;
2515 }
2516 vim_free(array[i]);
2517 ++i;
2518 ++extra;
2519 }
2520 }
2521
2522 /* Free any left-over old_len, as a result of an error */
2523 while (i < new_len)
2524 {
2525 vim_free(array[i]);
2526 ++i;
2527 }
2528
2529 /* Free the array of old_len. All of its contents have now
2530 * been dealt with (either freed, or the responsibility passed
2531 * to vim.
2532 */
2533 vim_free(array);
2534
2535 /* Adjust marks. Invalidate any which lie in the
2536 * changed range, and move any in the remainder of the buffer.
2537 */
2538 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2539 (long)MAXLNUM, (long)extra);
2540 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2541
Bram Moolenaar105bc352013-05-17 16:03:57 +02002542 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002543 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2544
Bram Moolenaar105bc352013-05-17 16:03:57 +02002545 // END of region without "return".
2546 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002547
2548 if (PyErr_Occurred() || VimErrorCheck())
2549 return FAIL;
2550
2551 if (len_change)
2552 *len_change = new_len - old_len;
2553
2554 return OK;
2555 }
2556 else
2557 {
2558 PyErr_BadArgument();
2559 return FAIL;
2560 }
2561}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002562
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002563/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002564 * The line number is in Vim format (1-based). The lines to be inserted are
2565 * given as a Python list of string objects or as a single string. The lines
2566 * to be added are checked for validity and correct format. Errors are
2567 * returned as a value of FAIL. The return value is OK on success.
2568 * If OK is returned and len_change is not NULL, *len_change
2569 * is set to the change in the buffer length.
2570 */
2571 static int
2572InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2573{
2574 /* First of all, we check the type of the supplied Python object.
2575 * It must be a string or a list, or the call is in error.
2576 */
2577 if (PyString_Check(lines))
2578 {
2579 char *str = StringToLine(lines);
2580 buf_T *savebuf;
2581
2582 if (str == NULL)
2583 return FAIL;
2584
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002585 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002586 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002587
2588 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2589 PyErr_SetVim(_("cannot save undo information"));
2590 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2591 PyErr_SetVim(_("cannot insert line"));
2592 else
2593 appended_lines_mark((linenr_T)n, 1L);
2594
2595 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002596 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002597 update_screen(VALID);
2598
2599 if (PyErr_Occurred() || VimErrorCheck())
2600 return FAIL;
2601
2602 if (len_change)
2603 *len_change = 1;
2604
2605 return OK;
2606 }
2607 else if (PyList_Check(lines))
2608 {
2609 PyInt i;
2610 PyInt size = PyList_Size(lines);
2611 char **array;
2612 buf_T *savebuf;
2613
2614 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2615 if (array == NULL)
2616 {
2617 PyErr_NoMemory();
2618 return FAIL;
2619 }
2620
2621 for (i = 0; i < size; ++i)
2622 {
2623 PyObject *line = PyList_GetItem(lines, i);
2624 array[i] = StringToLine(line);
2625
2626 if (array[i] == NULL)
2627 {
2628 while (i)
2629 vim_free(array[--i]);
2630 vim_free(array);
2631 return FAIL;
2632 }
2633 }
2634
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002635 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002636 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002637
2638 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2639 PyErr_SetVim(_("cannot save undo information"));
2640 else
2641 {
2642 for (i = 0; i < size; ++i)
2643 {
2644 if (ml_append((linenr_T)(n + i),
2645 (char_u *)array[i], 0, FALSE) == FAIL)
2646 {
2647 PyErr_SetVim(_("cannot insert line"));
2648
2649 /* Free the rest of the lines */
2650 while (i < size)
2651 vim_free(array[i++]);
2652
2653 break;
2654 }
2655 vim_free(array[i]);
2656 }
2657 if (i > 0)
2658 appended_lines_mark((linenr_T)n, (long)i);
2659 }
2660
2661 /* Free the array of lines. All of its contents have now
2662 * been freed.
2663 */
2664 vim_free(array);
2665
Bram Moolenaar105bc352013-05-17 16:03:57 +02002666 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002667 update_screen(VALID);
2668
2669 if (PyErr_Occurred() || VimErrorCheck())
2670 return FAIL;
2671
2672 if (len_change)
2673 *len_change = size;
2674
2675 return OK;
2676 }
2677 else
2678 {
2679 PyErr_BadArgument();
2680 return FAIL;
2681 }
2682}
2683
2684/*
2685 * Common routines for buffers and line ranges
2686 * -------------------------------------------
2687 */
2688
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002689typedef struct
2690{
2691 PyObject_HEAD
2692 buf_T *buf;
2693} BufferObject;
2694
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002695 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002696CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002697{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002698 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002699 {
2700 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2701 return -1;
2702 }
2703
2704 return 0;
2705}
2706
2707 static PyObject *
2708RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2709{
2710 if (CheckBuffer(self))
2711 return NULL;
2712
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002713 if (end == -1)
2714 end = self->buf->b_ml.ml_line_count;
2715
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002716 if (n < 0)
2717 n += end - start + 1;
2718
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002719 if (n < 0 || n > end - start)
2720 {
2721 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2722 return NULL;
2723 }
2724
2725 return GetBufferLine(self->buf, n+start);
2726}
2727
2728 static PyObject *
2729RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2730{
2731 PyInt size;
2732
2733 if (CheckBuffer(self))
2734 return NULL;
2735
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002736 if (end == -1)
2737 end = self->buf->b_ml.ml_line_count;
2738
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002739 size = end - start + 1;
2740
2741 if (lo < 0)
2742 lo = 0;
2743 else if (lo > size)
2744 lo = size;
2745 if (hi < 0)
2746 hi = 0;
2747 if (hi < lo)
2748 hi = lo;
2749 else if (hi > size)
2750 hi = size;
2751
2752 return GetBufferLineList(self->buf, lo+start, hi+start);
2753}
2754
2755 static PyInt
2756RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2757{
2758 PyInt len_change;
2759
2760 if (CheckBuffer(self))
2761 return -1;
2762
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002763 if (end == -1)
2764 end = self->buf->b_ml.ml_line_count;
2765
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002766 if (n < 0)
2767 n += end - start + 1;
2768
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002769 if (n < 0 || n > end - start)
2770 {
2771 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2772 return -1;
2773 }
2774
2775 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2776 return -1;
2777
2778 if (new_end)
2779 *new_end = end + len_change;
2780
2781 return 0;
2782}
2783
Bram Moolenaar19e60942011-06-19 00:27:51 +02002784 static PyInt
2785RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2786{
2787 PyInt size;
2788 PyInt len_change;
2789
2790 /* Self must be a valid buffer */
2791 if (CheckBuffer(self))
2792 return -1;
2793
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002794 if (end == -1)
2795 end = self->buf->b_ml.ml_line_count;
2796
Bram Moolenaar19e60942011-06-19 00:27:51 +02002797 /* Sort out the slice range */
2798 size = end - start + 1;
2799
2800 if (lo < 0)
2801 lo = 0;
2802 else if (lo > size)
2803 lo = size;
2804 if (hi < 0)
2805 hi = 0;
2806 if (hi < lo)
2807 hi = lo;
2808 else if (hi > size)
2809 hi = size;
2810
2811 if (SetBufferLineList(self->buf, lo + start, hi + start,
2812 val, &len_change) == FAIL)
2813 return -1;
2814
2815 if (new_end)
2816 *new_end = end + len_change;
2817
2818 return 0;
2819}
2820
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002821
2822 static PyObject *
2823RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2824{
2825 PyObject *lines;
2826 PyInt len_change;
2827 PyInt max;
2828 PyInt n;
2829
2830 if (CheckBuffer(self))
2831 return NULL;
2832
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002833 if (end == -1)
2834 end = self->buf->b_ml.ml_line_count;
2835
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002836 max = n = end - start + 1;
2837
2838 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2839 return NULL;
2840
2841 if (n < 0 || n > max)
2842 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002843 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002844 return NULL;
2845 }
2846
2847 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
2848 return NULL;
2849
2850 if (new_end)
2851 *new_end = end + len_change;
2852
2853 Py_INCREF(Py_None);
2854 return Py_None;
2855}
2856
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002857/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002858 */
2859
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002860static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002861static PySequenceMethods RangeAsSeq;
2862static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002863
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002864typedef struct
2865{
2866 PyObject_HEAD
2867 BufferObject *buf;
2868 PyInt start;
2869 PyInt end;
2870} RangeObject;
2871
2872 static PyObject *
2873RangeNew(buf_T *buf, PyInt start, PyInt end)
2874{
2875 BufferObject *bufr;
2876 RangeObject *self;
2877 self = PyObject_NEW(RangeObject, &RangeType);
2878 if (self == NULL)
2879 return NULL;
2880
2881 bufr = (BufferObject *)BufferNew(buf);
2882 if (bufr == NULL)
2883 {
2884 Py_DECREF(self);
2885 return NULL;
2886 }
2887 Py_INCREF(bufr);
2888
2889 self->buf = bufr;
2890 self->start = start;
2891 self->end = end;
2892
2893 return (PyObject *)(self);
2894}
2895
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002896 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002897RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002898{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002899 Py_DECREF(self->buf);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002900 DESTRUCTOR_FINISH(self);
2901}
2902
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002903 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002904RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002905{
2906 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002907 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002908 return -1; /* ??? */
2909
Bram Moolenaard6e39182013-05-21 18:30:34 +02002910 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002911}
2912
2913 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002914RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002915{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002916 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002917}
2918
2919 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002920RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002921{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002922 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002923}
2924
2925 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002926RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002927{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002928 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002929}
2930
2931 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002932RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002933{
2934 static char repr[100];
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002935
Bram Moolenaard6e39182013-05-21 18:30:34 +02002936 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002937 {
2938 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
2939 (self));
2940 return PyString_FromString(repr);
2941 }
2942 else
2943 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002944 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002945 int len;
2946
2947 if (name == NULL)
2948 name = "";
2949 len = (int)strlen(name);
2950
2951 if (len > 45)
2952 name = name + (45 - len);
2953
2954 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
2955 len > 45 ? "..." : "", name,
Bram Moolenaard6e39182013-05-21 18:30:34 +02002956 self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002957
2958 return PyString_FromString(repr);
2959 }
2960}
2961
2962static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02002963 /* name, function, calling, documentation */
2964 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
2965 { NULL, NULL, 0, NULL }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002966};
2967
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002968static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002969static PySequenceMethods BufferAsSeq;
2970static PyMappingMethods BufferAsMapping;
2971
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002972 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02002973BufferNew(buf_T *buf)
2974{
2975 /* We need to handle deletion of buffers underneath us.
2976 * If we add a "b_python*_ref" field to the buf_T structure,
2977 * then we can get at it in buf_freeall() in vim. We then
2978 * need to create only ONE Python object per buffer - if
2979 * we try to create a second, just INCREF the existing one
2980 * and return it. The (single) Python object referring to
2981 * the buffer is stored in "b_python*_ref".
2982 * Question: what to do on a buf_freeall(). We'll probably
2983 * have to either delete the Python object (DECREF it to
2984 * zero - a bad idea, as it leaves dangling refs!) or
2985 * set the buf_T * value to an invalid value (-1?), which
2986 * means we need checks in all access functions... Bah.
2987 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002988 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002989 * b_python_ref and b_python3_ref fields respectively.
2990 */
2991
2992 BufferObject *self;
2993
2994 if (BUF_PYTHON_REF(buf) != NULL)
2995 {
2996 self = BUF_PYTHON_REF(buf);
2997 Py_INCREF(self);
2998 }
2999 else
3000 {
3001 self = PyObject_NEW(BufferObject, &BufferType);
3002 if (self == NULL)
3003 return NULL;
3004 self->buf = buf;
3005 BUF_PYTHON_REF(buf) = self;
3006 }
3007
3008 return (PyObject *)(self);
3009}
3010
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003011 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003012BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003013{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003014 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3015 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003016
3017 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003018}
3019
Bram Moolenaar971db462013-05-12 18:44:48 +02003020 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003021BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003022{
3023 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003024 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003025 return -1; /* ??? */
3026
Bram Moolenaard6e39182013-05-21 18:30:34 +02003027 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003028}
3029
3030 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003031BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003032{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003033 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003034}
3035
3036 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003037BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003038{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003039 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003040}
3041
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003042 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003043BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003044{
3045 if (strcmp(name, "name") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003046 return Py_BuildValue("s", self->buf->b_ffname);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003047 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003048 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003049 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003050 return DictionaryNew(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003051 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003052 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3053 (PyObject *) self);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003054 else if (strcmp(name,"__members__") == 0)
3055 return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
3056 else
3057 return NULL;
3058}
3059
3060 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003061BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003062{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003063 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003064}
3065
3066 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003067BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003068{
3069 pos_T *posp;
3070 char *pmark;
3071 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02003072 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003073
Bram Moolenaard6e39182013-05-21 18:30:34 +02003074 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003075 return NULL;
3076
3077 if (!PyArg_ParseTuple(args, "s", &pmark))
3078 return NULL;
3079 mark = *pmark;
3080
Bram Moolenaard6e39182013-05-21 18:30:34 +02003081 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003082 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003083 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003084
3085 if (posp == NULL)
3086 {
3087 PyErr_SetVim(_("invalid mark name"));
3088 return NULL;
3089 }
3090
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02003091 /* Check for keyboard interrupt */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003092 if (VimErrorCheck())
3093 return NULL;
3094
3095 if (posp->lnum <= 0)
3096 {
3097 /* Or raise an error? */
3098 Py_INCREF(Py_None);
3099 return Py_None;
3100 }
3101
3102 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3103}
3104
3105 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003106BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003107{
3108 PyInt start;
3109 PyInt end;
3110
Bram Moolenaard6e39182013-05-21 18:30:34 +02003111 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003112 return NULL;
3113
3114 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3115 return NULL;
3116
Bram Moolenaard6e39182013-05-21 18:30:34 +02003117 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003118}
3119
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003120 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003121BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003122{
3123 static char repr[100];
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003124
Bram Moolenaard6e39182013-05-21 18:30:34 +02003125 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003126 {
3127 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3128 return PyString_FromString(repr);
3129 }
3130 else
3131 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003132 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003133 PyInt len;
3134
3135 if (name == NULL)
3136 name = "";
3137 len = strlen(name);
3138
3139 if (len > 35)
3140 name = name + (35 - len);
3141
3142 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3143
3144 return PyString_FromString(repr);
3145 }
3146}
3147
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003148static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003149 /* name, function, calling, documentation */
3150 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
3151 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
3152 {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01003153#if PY_VERSION_HEX >= 0x03000000
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003154 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, "List buffer attributes" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01003155#endif
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003156 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003157};
3158
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003159/*
3160 * Buffer list object - Implementation
3161 */
3162
3163static PyTypeObject BufMapType;
3164
3165typedef struct
3166{
3167 PyObject_HEAD
3168} BufMapObject;
3169
3170 static PyInt
3171BufMapLength(PyObject *self UNUSED)
3172{
3173 buf_T *b = firstbuf;
3174 PyInt n = 0;
3175
3176 while (b)
3177 {
3178 ++n;
3179 b = b->b_next;
3180 }
3181
3182 return n;
3183}
3184
3185 static PyObject *
3186BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3187{
3188 buf_T *b;
3189 int bnr;
3190
3191#if PY_MAJOR_VERSION < 3
3192 if (PyInt_Check(keyObject))
3193 bnr = PyInt_AsLong(keyObject);
3194 else
3195#endif
3196 if (PyLong_Check(keyObject))
3197 bnr = PyLong_AsLong(keyObject);
3198 else
3199 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003200 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003201 return NULL;
3202 }
3203
3204 b = buflist_findnr(bnr);
3205
3206 if (b)
3207 return BufferNew(b);
3208 else
3209 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003210 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003211 return NULL;
3212 }
3213}
3214
3215 static void
3216BufMapIterDestruct(PyObject *buffer)
3217{
3218 /* Iteration was stopped before all buffers were processed */
3219 if (buffer)
3220 {
3221 Py_DECREF(buffer);
3222 }
3223}
3224
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003225 static int
3226BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
3227{
3228 Py_VISIT(buffer);
3229 return 0;
3230}
3231
3232 static int
3233BufMapIterClear(PyObject **buffer)
3234{
3235 Py_CLEAR(*buffer);
3236 return 0;
3237}
3238
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003239 static PyObject *
3240BufMapIterNext(PyObject **buffer)
3241{
3242 PyObject *next;
3243 PyObject *r;
3244
3245 if (!*buffer)
3246 return NULL;
3247
3248 r = *buffer;
3249
3250 if (CheckBuffer((BufferObject *)(r)))
3251 {
3252 *buffer = NULL;
3253 return NULL;
3254 }
3255
3256 if (!((BufferObject *)(r))->buf->b_next)
3257 next = NULL;
3258 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3259 return NULL;
3260 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02003261 /* Do not increment reference: we no longer hold it (decref), but whoever
3262 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003263 return r;
3264}
3265
3266 static PyObject *
3267BufMapIter(PyObject *self UNUSED)
3268{
3269 PyObject *buffer;
3270
3271 buffer = BufferNew(firstbuf);
3272 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003273 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
3274 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003275}
3276
3277static PyMappingMethods BufMapAsMapping = {
3278 (lenfunc) BufMapLength,
3279 (binaryfunc) BufMapItem,
3280 (objobjargproc) 0,
3281};
3282
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003283/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003284 */
3285
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003286 static PyObject *
3287CurrentGetattr(PyObject *self UNUSED, char *name)
3288{
3289 if (strcmp(name, "buffer") == 0)
3290 return (PyObject *)BufferNew(curbuf);
3291 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003292 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003293 else if (strcmp(name, "tabpage") == 0)
3294 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003295 else if (strcmp(name, "line") == 0)
3296 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3297 else if (strcmp(name, "range") == 0)
3298 return RangeNew(curbuf, RangeStart, RangeEnd);
3299 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003300 return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
3301 "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003302 else
3303 {
3304 PyErr_SetString(PyExc_AttributeError, name);
3305 return NULL;
3306 }
3307}
3308
3309 static int
3310CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3311{
3312 if (strcmp(name, "line") == 0)
3313 {
3314 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3315 return -1;
3316
3317 return 0;
3318 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003319 else if (strcmp(name, "buffer") == 0)
3320 {
3321 int count;
3322
3323 if (value->ob_type != &BufferType)
3324 {
3325 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3326 return -1;
3327 }
3328
3329 if (CheckBuffer((BufferObject *)(value)))
3330 return -1;
3331 count = ((BufferObject *)(value))->buf->b_fnum;
3332
3333 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3334 {
3335 PyErr_SetVim(_("failed to switch to given buffer"));
3336 return -1;
3337 }
3338
3339 return 0;
3340 }
3341 else if (strcmp(name, "window") == 0)
3342 {
3343 int count;
3344
3345 if (value->ob_type != &WindowType)
3346 {
3347 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3348 return -1;
3349 }
3350
3351 if (CheckWindow((WindowObject *)(value)))
3352 return -1;
3353 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3354
3355 if (!count)
3356 {
3357 PyErr_SetString(PyExc_ValueError,
3358 _("failed to find window in the current tab page"));
3359 return -1;
3360 }
3361
3362 win_goto(((WindowObject *)(value))->win);
3363 if (((WindowObject *)(value))->win != curwin)
3364 {
3365 PyErr_SetString(PyExc_RuntimeError,
3366 _("did not switch to the specified window"));
3367 return -1;
3368 }
3369
3370 return 0;
3371 }
3372 else if (strcmp(name, "tabpage") == 0)
3373 {
3374 if (value->ob_type != &TabPageType)
3375 {
3376 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3377 return -1;
3378 }
3379
3380 if (CheckTabPage((TabPageObject *)(value)))
3381 return -1;
3382
3383 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3384 if (((TabPageObject *)(value))->tab != curtab)
3385 {
3386 PyErr_SetString(PyExc_RuntimeError,
3387 _("did not switch to the specified tab page"));
3388 return -1;
3389 }
3390
3391 return 0;
3392 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003393 else
3394 {
3395 PyErr_SetString(PyExc_AttributeError, name);
3396 return -1;
3397 }
3398}
3399
Bram Moolenaardb913952012-06-29 12:54:53 +02003400 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003401init_range_cmd(exarg_T *eap)
3402{
3403 RangeStart = eap->line1;
3404 RangeEnd = eap->line2;
3405}
3406
3407 static void
3408init_range_eval(typval_T *rettv UNUSED)
3409{
3410 RangeStart = (PyInt) curwin->w_cursor.lnum;
3411 RangeEnd = RangeStart;
3412}
3413
3414 static void
3415run_cmd(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate UNUSED)
3416{
3417 PyRun_SimpleString((char *) cmd);
3418}
3419
3420static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
3421static int code_hdr_len = 30;
3422
3423 static void
3424run_do(const char *cmd, void *arg UNUSED, PyGILState_STATE *pygilstate)
3425{
3426 PyInt lnum;
3427 size_t len;
3428 char *code;
3429 int status;
3430 PyObject *pyfunc, *pymain;
3431
3432 if (u_save(RangeStart - 1, RangeEnd + 1) != OK)
3433 {
3434 EMSG(_("cannot save undo information"));
3435 return;
3436 }
3437
3438 len = code_hdr_len + STRLEN(cmd);
3439 code = PyMem_New(char, len + 1);
3440 memcpy(code, code_hdr, code_hdr_len);
3441 STRCPY(code + code_hdr_len, cmd);
3442 status = PyRun_SimpleString(code);
3443 PyMem_Free(code);
3444
3445 if (status)
3446 {
3447 EMSG(_("failed to run the code"));
3448 return;
3449 }
3450
3451 status = 0;
3452 pymain = PyImport_AddModule("__main__");
3453 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
3454 PyGILState_Release(*pygilstate);
3455
3456 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
3457 {
3458 PyObject *line, *linenr, *ret;
3459
3460 *pygilstate = PyGILState_Ensure();
3461 if (!(line = GetBufferLine(curbuf, lnum)))
3462 goto err;
3463 if (!(linenr = PyInt_FromLong((long) lnum)))
3464 {
3465 Py_DECREF(line);
3466 goto err;
3467 }
3468 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
3469 Py_DECREF(line);
3470 Py_DECREF(linenr);
3471 if (!ret)
3472 goto err;
3473
3474 if (ret != Py_None)
3475 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
3476 goto err;
3477
3478 Py_XDECREF(ret);
3479 PythonIO_Flush();
3480 PyGILState_Release(*pygilstate);
3481 }
3482 goto out;
3483err:
3484 *pygilstate = PyGILState_Ensure();
3485 PyErr_PrintEx(0);
3486 PythonIO_Flush();
3487 status = 1;
3488out:
3489 if (!status)
3490 *pygilstate = PyGILState_Ensure();
3491 Py_DECREF(pyfunc);
3492 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
3493 if (status)
3494 return;
3495 check_cursor();
3496 update_curbuf(NOT_VALID);
3497}
3498
3499 static void
3500run_eval(const char *cmd, typval_T *rettv, PyGILState_STATE *pygilstate UNUSED)
3501{
3502 PyObject *r;
3503
3504 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
3505 if (r == NULL)
3506 {
3507 if (PyErr_Occurred() && !msg_silent)
3508 PyErr_PrintEx(0);
3509 EMSG(_("E858: Eval did not return a valid python object"));
3510 }
3511 else
3512 {
3513 if (ConvertFromPyObject(r, rettv) == -1)
3514 EMSG(_("E859: Failed to convert returned python object to vim value"));
3515 Py_DECREF(r);
3516 }
3517 PyErr_Clear();
3518}
3519
3520 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02003521set_ref_in_py(const int copyID)
3522{
3523 pylinkedlist_T *cur;
3524 dict_T *dd;
3525 list_T *ll;
3526
3527 if (lastdict != NULL)
3528 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3529 {
3530 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3531 if (dd->dv_copyID != copyID)
3532 {
3533 dd->dv_copyID = copyID;
3534 set_ref_in_ht(&dd->dv_hashtab, copyID);
3535 }
3536 }
3537
3538 if (lastlist != NULL)
3539 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3540 {
3541 ll = ((ListObject *) (cur->pll_obj))->list;
3542 if (ll->lv_copyID != copyID)
3543 {
3544 ll->lv_copyID = copyID;
3545 set_ref_in_list(ll, copyID);
3546 }
3547 }
3548}
3549
3550 static int
3551set_string_copy(char_u *str, typval_T *tv)
3552{
3553 tv->vval.v_string = vim_strsave(str);
3554 if (tv->vval.v_string == NULL)
3555 {
3556 PyErr_NoMemory();
3557 return -1;
3558 }
3559 return 0;
3560}
3561
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003562 static int
3563pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3564{
3565 dict_T *d;
3566 char_u *key;
3567 dictitem_T *di;
3568 PyObject *keyObject;
3569 PyObject *valObject;
3570 Py_ssize_t iter = 0;
3571
3572 d = dict_alloc();
3573 if (d == NULL)
3574 {
3575 PyErr_NoMemory();
3576 return -1;
3577 }
3578
3579 tv->v_type = VAR_DICT;
3580 tv->vval.v_dict = d;
3581
3582 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
3583 {
3584 DICTKEY_DECL
3585
3586 if (keyObject == NULL)
3587 return -1;
3588 if (valObject == NULL)
3589 return -1;
3590
3591 DICTKEY_GET_NOTEMPTY(-1)
3592
3593 di = dictitem_alloc(key);
3594
3595 DICTKEY_UNREF
3596
3597 if (di == NULL)
3598 {
3599 PyErr_NoMemory();
3600 return -1;
3601 }
3602 di->di_tv.v_lock = 0;
3603
3604 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3605 {
3606 vim_free(di);
3607 return -1;
3608 }
3609 if (dict_add(d, di) == FAIL)
3610 {
3611 vim_free(di);
3612 PyErr_SetVim(_("failed to add key to dictionary"));
3613 return -1;
3614 }
3615 }
3616 return 0;
3617}
3618
3619 static int
3620pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3621{
3622 dict_T *d;
3623 char_u *key;
3624 dictitem_T *di;
3625 PyObject *list;
3626 PyObject *litem;
3627 PyObject *keyObject;
3628 PyObject *valObject;
3629 Py_ssize_t lsize;
3630
3631 d = dict_alloc();
3632 if (d == NULL)
3633 {
3634 PyErr_NoMemory();
3635 return -1;
3636 }
3637
3638 tv->v_type = VAR_DICT;
3639 tv->vval.v_dict = d;
3640
3641 list = PyMapping_Items(obj);
3642 if (list == NULL)
3643 return -1;
3644 lsize = PyList_Size(list);
3645 while (lsize--)
3646 {
3647 DICTKEY_DECL
3648
3649 litem = PyList_GetItem(list, lsize);
3650 if (litem == NULL)
3651 {
3652 Py_DECREF(list);
3653 return -1;
3654 }
3655
3656 keyObject = PyTuple_GetItem(litem, 0);
3657 if (keyObject == NULL)
3658 {
3659 Py_DECREF(list);
3660 Py_DECREF(litem);
3661 return -1;
3662 }
3663
3664 DICTKEY_GET_NOTEMPTY(-1)
3665
3666 valObject = PyTuple_GetItem(litem, 1);
3667 if (valObject == NULL)
3668 {
3669 Py_DECREF(list);
3670 Py_DECREF(litem);
3671 return -1;
3672 }
3673
3674 di = dictitem_alloc(key);
3675
3676 DICTKEY_UNREF
3677
3678 if (di == NULL)
3679 {
3680 Py_DECREF(list);
3681 Py_DECREF(litem);
3682 PyErr_NoMemory();
3683 return -1;
3684 }
3685 di->di_tv.v_lock = 0;
3686
3687 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3688 {
3689 vim_free(di);
3690 Py_DECREF(list);
3691 Py_DECREF(litem);
3692 return -1;
3693 }
3694 if (dict_add(d, di) == FAIL)
3695 {
3696 vim_free(di);
3697 Py_DECREF(list);
3698 Py_DECREF(litem);
3699 PyErr_SetVim(_("failed to add key to dictionary"));
3700 return -1;
3701 }
3702 Py_DECREF(litem);
3703 }
3704 Py_DECREF(list);
3705 return 0;
3706}
3707
3708 static int
3709pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3710{
3711 list_T *l;
3712
3713 l = list_alloc();
3714 if (l == NULL)
3715 {
3716 PyErr_NoMemory();
3717 return -1;
3718 }
3719
3720 tv->v_type = VAR_LIST;
3721 tv->vval.v_list = l;
3722
3723 if (list_py_concat(l, obj, lookupDict) == -1)
3724 return -1;
3725
3726 return 0;
3727}
3728
3729 static int
3730pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3731{
3732 PyObject *iterator = PyObject_GetIter(obj);
3733 PyObject *item;
3734 list_T *l;
3735 listitem_T *li;
3736
3737 l = list_alloc();
3738
3739 if (l == NULL)
3740 {
3741 PyErr_NoMemory();
3742 return -1;
3743 }
3744
3745 tv->vval.v_list = l;
3746 tv->v_type = VAR_LIST;
3747
3748
3749 if (iterator == NULL)
3750 return -1;
3751
3752 while ((item = PyIter_Next(obj)))
3753 {
3754 li = listitem_alloc();
3755 if (li == NULL)
3756 {
3757 PyErr_NoMemory();
3758 return -1;
3759 }
3760 li->li_tv.v_lock = 0;
3761
3762 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
3763 return -1;
3764
3765 list_append(l, li);
3766
3767 Py_DECREF(item);
3768 }
3769
3770 Py_DECREF(iterator);
3771 return 0;
3772}
3773
Bram Moolenaardb913952012-06-29 12:54:53 +02003774typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
3775
3776 static int
3777convert_dl(PyObject *obj, typval_T *tv,
3778 pytotvfunc py_to_tv, PyObject *lookupDict)
3779{
3780 PyObject *capsule;
3781 char hexBuf[sizeof(void *) * 2 + 3];
3782
3783 sprintf(hexBuf, "%p", obj);
3784
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003785# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003786 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003787# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003788 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003789# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02003790 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02003791 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003792# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02003793 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02003794# else
3795 capsule = PyCObject_FromVoidPtr(tv, NULL);
3796# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003797 PyDict_SetItemString(lookupDict, hexBuf, capsule);
3798 Py_DECREF(capsule);
3799 if (py_to_tv(obj, tv, lookupDict) == -1)
3800 {
3801 tv->v_type = VAR_UNKNOWN;
3802 return -1;
3803 }
3804 /* As we are not using copy_tv which increments reference count we must
3805 * do it ourself. */
3806 switch(tv->v_type)
3807 {
3808 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
3809 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
3810 }
3811 }
3812 else
3813 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003814 typval_T *v;
3815
3816# ifdef PY_USE_CAPSULE
3817 v = PyCapsule_GetPointer(capsule, NULL);
3818# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02003819 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02003820# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02003821 copy_tv(v, tv);
3822 }
3823 return 0;
3824}
3825
3826 static int
3827ConvertFromPyObject(PyObject *obj, typval_T *tv)
3828{
3829 PyObject *lookup_dict;
3830 int r;
3831
3832 lookup_dict = PyDict_New();
3833 r = _ConvertFromPyObject(obj, tv, lookup_dict);
3834 Py_DECREF(lookup_dict);
3835 return r;
3836}
3837
3838 static int
3839_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3840{
3841 if (obj->ob_type == &DictionaryType)
3842 {
3843 tv->v_type = VAR_DICT;
3844 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
3845 ++tv->vval.v_dict->dv_refcount;
3846 }
3847 else if (obj->ob_type == &ListType)
3848 {
3849 tv->v_type = VAR_LIST;
3850 tv->vval.v_list = (((ListObject *)(obj))->list);
3851 ++tv->vval.v_list->lv_refcount;
3852 }
3853 else if (obj->ob_type == &FunctionType)
3854 {
3855 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
3856 return -1;
3857
3858 tv->v_type = VAR_FUNC;
3859 func_ref(tv->vval.v_string);
3860 }
Bram Moolenaardb913952012-06-29 12:54:53 +02003861 else if (PyBytes_Check(obj))
3862 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003863 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02003864
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003865 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
3866 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003867 if (result == NULL)
3868 return -1;
3869
3870 if (set_string_copy(result, tv) == -1)
3871 return -1;
3872
3873 tv->v_type = VAR_STRING;
3874 }
3875 else if (PyUnicode_Check(obj))
3876 {
3877 PyObject *bytes;
3878 char_u *result;
3879
Bram Moolenaardb913952012-06-29 12:54:53 +02003880 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
3881 if (bytes == NULL)
3882 return -1;
3883
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02003884 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
3885 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02003886 if (result == NULL)
3887 return -1;
3888
3889 if (set_string_copy(result, tv) == -1)
3890 {
3891 Py_XDECREF(bytes);
3892 return -1;
3893 }
3894 Py_XDECREF(bytes);
3895
3896 tv->v_type = VAR_STRING;
3897 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02003898#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02003899 else if (PyInt_Check(obj))
3900 {
3901 tv->v_type = VAR_NUMBER;
3902 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
3903 }
3904#endif
3905 else if (PyLong_Check(obj))
3906 {
3907 tv->v_type = VAR_NUMBER;
3908 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
3909 }
3910 else if (PyDict_Check(obj))
3911 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
3912#ifdef FEAT_FLOAT
3913 else if (PyFloat_Check(obj))
3914 {
3915 tv->v_type = VAR_FLOAT;
3916 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
3917 }
3918#endif
3919 else if (PyIter_Check(obj))
3920 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
3921 else if (PySequence_Check(obj))
3922 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
3923 else if (PyMapping_Check(obj))
3924 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
3925 else
3926 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003927 PyErr_SetString(PyExc_TypeError,
3928 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02003929 return -1;
3930 }
3931 return 0;
3932}
3933
3934 static PyObject *
3935ConvertToPyObject(typval_T *tv)
3936{
3937 if (tv == NULL)
3938 {
3939 PyErr_SetVim(_("NULL reference passed"));
3940 return NULL;
3941 }
3942 switch (tv->v_type)
3943 {
3944 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003945 return PyBytes_FromString(tv->vval.v_string == NULL
3946 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003947 case VAR_NUMBER:
3948 return PyLong_FromLong((long) tv->vval.v_number);
3949#ifdef FEAT_FLOAT
3950 case VAR_FLOAT:
3951 return PyFloat_FromDouble((double) tv->vval.v_float);
3952#endif
3953 case VAR_LIST:
3954 return ListNew(tv->vval.v_list);
3955 case VAR_DICT:
3956 return DictionaryNew(tv->vval.v_dict);
3957 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02003958 return FunctionNew(tv->vval.v_string == NULL
3959 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02003960 case VAR_UNKNOWN:
3961 Py_INCREF(Py_None);
3962 return Py_None;
3963 default:
3964 PyErr_SetVim(_("internal error: invalid value type"));
3965 return NULL;
3966 }
3967}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003968
3969typedef struct
3970{
3971 PyObject_HEAD
3972} CurrentObject;
3973static PyTypeObject CurrentType;
3974
3975 static void
3976init_structs(void)
3977{
3978 vim_memset(&OutputType, 0, sizeof(OutputType));
3979 OutputType.tp_name = "vim.message";
3980 OutputType.tp_basicsize = sizeof(OutputObject);
3981 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
3982 OutputType.tp_doc = "vim message object";
3983 OutputType.tp_methods = OutputMethods;
3984#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02003985 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
3986 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003987 OutputType.tp_alloc = call_PyType_GenericAlloc;
3988 OutputType.tp_new = call_PyType_GenericNew;
3989 OutputType.tp_free = call_PyObject_Free;
3990#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02003991 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
3992 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003993#endif
3994
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003995 vim_memset(&IterType, 0, sizeof(IterType));
3996 IterType.tp_name = "vim.iter";
3997 IterType.tp_basicsize = sizeof(IterObject);
3998 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
3999 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004000 IterType.tp_iter = (getiterfunc)IterIter;
4001 IterType.tp_iternext = (iternextfunc)IterNext;
4002 IterType.tp_dealloc = (destructor)IterDestructor;
4003 IterType.tp_traverse = (traverseproc)IterTraverse;
4004 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004005
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004006 vim_memset(&BufferType, 0, sizeof(BufferType));
4007 BufferType.tp_name = "vim.buffer";
4008 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004009 BufferType.tp_dealloc = (destructor)BufferDestructor;
4010 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004011 BufferType.tp_as_sequence = &BufferAsSeq;
4012 BufferType.tp_as_mapping = &BufferAsMapping;
4013 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
4014 BufferType.tp_doc = "vim buffer object";
4015 BufferType.tp_methods = BufferMethods;
4016#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004017 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004018 BufferType.tp_alloc = call_PyType_GenericAlloc;
4019 BufferType.tp_new = call_PyType_GenericNew;
4020 BufferType.tp_free = call_PyObject_Free;
4021#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004022 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004023#endif
4024
4025 vim_memset(&WindowType, 0, sizeof(WindowType));
4026 WindowType.tp_name = "vim.window";
4027 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004028 WindowType.tp_dealloc = (destructor)WindowDestructor;
4029 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004030 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
4031 WindowType.tp_doc = "vim Window object";
4032 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004033 WindowType.tp_traverse = (traverseproc)WindowTraverse;
4034 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004035#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004036 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
4037 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004038 WindowType.tp_alloc = call_PyType_GenericAlloc;
4039 WindowType.tp_new = call_PyType_GenericNew;
4040 WindowType.tp_free = call_PyObject_Free;
4041#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004042 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
4043 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004044#endif
4045
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004046 vim_memset(&TabPageType, 0, sizeof(TabPageType));
4047 TabPageType.tp_name = "vim.tabpage";
4048 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004049 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
4050 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004051 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
4052 TabPageType.tp_doc = "vim tab page object";
4053 TabPageType.tp_methods = TabPageMethods;
4054#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004055 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004056 TabPageType.tp_alloc = call_PyType_GenericAlloc;
4057 TabPageType.tp_new = call_PyType_GenericNew;
4058 TabPageType.tp_free = call_PyObject_Free;
4059#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004060 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004061#endif
4062
Bram Moolenaardfa38d42013-05-15 13:38:47 +02004063 vim_memset(&BufMapType, 0, sizeof(BufMapType));
4064 BufMapType.tp_name = "vim.bufferlist";
4065 BufMapType.tp_basicsize = sizeof(BufMapObject);
4066 BufMapType.tp_as_mapping = &BufMapAsMapping;
4067 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004068 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004069 BufferType.tp_doc = "vim buffer list";
4070
4071 vim_memset(&WinListType, 0, sizeof(WinListType));
4072 WinListType.tp_name = "vim.windowlist";
4073 WinListType.tp_basicsize = sizeof(WinListType);
4074 WinListType.tp_as_sequence = &WinListAsSeq;
4075 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
4076 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004077 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004078
4079 vim_memset(&TabListType, 0, sizeof(TabListType));
4080 TabListType.tp_name = "vim.tabpagelist";
4081 TabListType.tp_basicsize = sizeof(TabListType);
4082 TabListType.tp_as_sequence = &TabListAsSeq;
4083 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
4084 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004085
4086 vim_memset(&RangeType, 0, sizeof(RangeType));
4087 RangeType.tp_name = "vim.range";
4088 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004089 RangeType.tp_dealloc = (destructor)RangeDestructor;
4090 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004091 RangeType.tp_as_sequence = &RangeAsSeq;
4092 RangeType.tp_as_mapping = &RangeAsMapping;
4093 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
4094 RangeType.tp_doc = "vim Range object";
4095 RangeType.tp_methods = RangeMethods;
4096#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004097 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004098 RangeType.tp_alloc = call_PyType_GenericAlloc;
4099 RangeType.tp_new = call_PyType_GenericNew;
4100 RangeType.tp_free = call_PyObject_Free;
4101#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004102 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004103#endif
4104
4105 vim_memset(&CurrentType, 0, sizeof(CurrentType));
4106 CurrentType.tp_name = "vim.currentdata";
4107 CurrentType.tp_basicsize = sizeof(CurrentObject);
4108 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
4109 CurrentType.tp_doc = "vim current object";
4110#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004111 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
4112 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004113#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004114 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
4115 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004116#endif
4117
4118 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
4119 DictionaryType.tp_name = "vim.dictionary";
4120 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004121 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004122 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
4123 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
4124 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
4125 DictionaryType.tp_methods = DictionaryMethods;
4126#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004127 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
4128 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004129#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004130 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
4131 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004132#endif
4133
4134 vim_memset(&ListType, 0, sizeof(ListType));
4135 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004136 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004137 ListType.tp_basicsize = sizeof(ListObject);
4138 ListType.tp_as_sequence = &ListAsSeq;
4139 ListType.tp_as_mapping = &ListAsMapping;
4140 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
4141 ListType.tp_doc = "list pushing modifications to vim structure";
4142 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004143 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004144#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004145 ListType.tp_getattro = (getattrofunc)ListGetattro;
4146 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004147#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004148 ListType.tp_getattr = (getattrfunc)ListGetattr;
4149 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004150#endif
4151
4152 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004153 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004154 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004155 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
4156 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004157 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
4158 FunctionType.tp_doc = "object that calls vim function";
4159 FunctionType.tp_methods = FunctionMethods;
4160#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004161 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004162#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004163 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004164#endif
4165
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004166 vim_memset(&OptionsType, 0, sizeof(OptionsType));
4167 OptionsType.tp_name = "vim.options";
4168 OptionsType.tp_basicsize = sizeof(OptionsObject);
4169 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
4170 OptionsType.tp_doc = "object for manipulating options";
4171 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004172 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
4173 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
4174 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004175
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004176#if PY_MAJOR_VERSION >= 3
4177 vim_memset(&vimmodule, 0, sizeof(vimmodule));
4178 vimmodule.m_name = "vim";
4179 vimmodule.m_doc = "Vim Python interface\n";
4180 vimmodule.m_size = -1;
4181 vimmodule.m_methods = VimMethods;
4182#endif
4183}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004184
4185#define PYTYPE_READY(type) \
4186 if (PyType_Ready(&type)) \
4187 return -1;
4188
4189 static int
4190init_types()
4191{
4192 PYTYPE_READY(IterType);
4193 PYTYPE_READY(BufferType);
4194 PYTYPE_READY(RangeType);
4195 PYTYPE_READY(WindowType);
4196 PYTYPE_READY(TabPageType);
4197 PYTYPE_READY(BufMapType);
4198 PYTYPE_READY(WinListType);
4199 PYTYPE_READY(TabListType);
4200 PYTYPE_READY(CurrentType);
4201 PYTYPE_READY(DictionaryType);
4202 PYTYPE_READY(ListType);
4203 PYTYPE_READY(FunctionType);
4204 PYTYPE_READY(OptionsType);
4205 PYTYPE_READY(OutputType);
4206 return 0;
4207}
4208
4209static BufMapObject TheBufferMap =
4210{
4211 PyObject_HEAD_INIT(&BufMapType)
4212};
4213
4214static WinListObject TheWindowList =
4215{
4216 PyObject_HEAD_INIT(&WinListType)
4217 NULL
4218};
4219
4220static CurrentObject TheCurrent =
4221{
4222 PyObject_HEAD_INIT(&CurrentType)
4223};
4224
4225static TabListObject TheTabPageList =
4226{
4227 PyObject_HEAD_INIT(&TabListType)
4228};
4229
4230static struct numeric_constant {
4231 char *name;
4232 int value;
4233} numeric_constants[] = {
4234 {"VAR_LOCKED", VAR_LOCKED},
4235 {"VAR_FIXED", VAR_FIXED},
4236 {"VAR_SCOPE", VAR_SCOPE},
4237 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
4238};
4239
4240static struct object_constant {
4241 char *name;
4242 PyObject *value;
4243} object_constants[] = {
4244 {"buffers", (PyObject *)(void *)&TheBufferMap},
4245 {"windows", (PyObject *)(void *)&TheWindowList},
4246 {"tabpages", (PyObject *)(void *)&TheTabPageList},
4247 {"current", (PyObject *)(void *)&TheCurrent},
4248};
4249
4250typedef int (*object_adder)(PyObject *, const char *, PyObject *);
4251
4252#define ADD_OBJECT(m, name, obj) \
4253 if (add_object(m, name, obj)) \
4254 return -1;
4255
4256#define ADD_CHECKED_OBJECT(m, name, obj) \
4257 { \
4258 PyObject *value = obj; \
4259 if (!value) \
4260 return -1; \
4261 ADD_OBJECT(m, name, value); \
4262 }
4263
4264 static int
4265populate_module(PyObject *m, object_adder add_object)
4266{
4267 int i;
4268
4269 for (i = 0; i < (int)(sizeof(numeric_constants)
4270 / sizeof(struct numeric_constant));
4271 ++i)
4272 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
4273 PyInt_FromLong(numeric_constants[i].value));
4274
4275 for (i = 0; i < (int)(sizeof(object_constants)
4276 / sizeof(struct object_constant));
4277 ++i)
4278 {
4279 PyObject *value;
4280
4281 value = object_constants[i].value;
4282 Py_INCREF(value);
4283 ADD_OBJECT(m, object_constants[i].name, value);
4284 }
4285
4286 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
4287 return -1;
4288 ADD_OBJECT(m, "error", VimError);
4289
4290 ADD_CHECKED_OBJECT(m, "vars", DictionaryNew(&globvardict));
4291 ADD_CHECKED_OBJECT(m, "vvars", DictionaryNew(&vimvardict));
4292 ADD_CHECKED_OBJECT(m, "options",
4293 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
4294 return 0;
4295}