blob: c1464331f447295b39c8c2f355fc99e1ec3e405d [file] [log] [blame]
Bram Moolenaardb913952012-06-29 12:54:53 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02002 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020010 * Python extensions by Paul Moore, David Leonard, Roland Puntaier, Nikolay
11 * Pavlov.
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020012 *
13 * Common code for if_python.c and if_python3.c.
14 */
15
Bram Moolenaarc1a995d2012-08-08 16:05:07 +020016#if PY_VERSION_HEX < 0x02050000
17typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
18#endif
19
Bram Moolenaar91805fc2011-06-26 04:01:44 +020020#ifdef FEAT_MBYTE
21# define ENC_OPT p_enc
22#else
23# define ENC_OPT "latin1"
24#endif
Bram Moolenaard620aa92013-05-17 16:40:06 +020025#define DOPY_FUNC "_vim_pydo"
Bram Moolenaar91805fc2011-06-26 04:01:44 +020026
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020027#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
28
29#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
30#define INVALID_WINDOW_VALUE ((win_T *)(-1))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +020031#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020032
Bram Moolenaare9ba5162013-05-29 22:02:22 +020033#define DICTKEY_DECL \
34 PyObject *dictkey_todecref;
35#define DICTKEY_GET(err) \
36 if (!(key = StringToChars(keyObject, &dictkey_todecref))) \
37 return err;
38#define DICTKEY_UNREF \
39 Py_XDECREF(dictkey_todecref);
40
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020041typedef void (*rangeinitializer)(void *);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +020042typedef void (*runner)(const char *, void *
43#ifdef PY_CAN_RECURSE
44 , PyGILState_STATE *
45#endif
46 );
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020047
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020048static int ConvertFromPyObject(PyObject *, typval_T *);
49static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +020050static PyObject *WindowNew(win_T *, tabpage_T *);
51static PyObject *BufferNew (buf_T *);
52static PyObject *LineToString(const char *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +020053
54static PyInt RangeStart;
55static PyInt RangeEnd;
56
Bram Moolenaarb52f4c02013-05-21 18:19:38 +020057static PyObject *globals;
58
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020059/*
60 * obtain a lock on the Vim data structures
61 */
62 static void
63Python_Lock_Vim(void)
64{
65}
66
67/*
68 * release a lock on the Vim data structures
69 */
70 static void
71Python_Release_Vim(void)
72{
73}
74
Bram Moolenaare9ba5162013-05-29 22:02:22 +020075/*
76 * The "todecref" argument holds a pointer to PyObject * that must be
77 * DECREF'ed after returned char_u * is no longer needed or NULL if all what
78 * was needed to generate returned value is object.
79 *
80 * Use Py_XDECREF to decrement reference count.
81 */
82 static char_u *
83StringToChars(PyObject *object, PyObject **todecref)
84{
85 char_u *p;
86 PyObject *bytes = NULL;
87
88 if (PyBytes_Check(object))
89 {
90
91 if (PyString_AsStringAndSize(object, (char **) &p, NULL) == -1)
92 return NULL;
93 if (p == NULL)
94 return NULL;
95
96 *todecref = NULL;
97 }
98 else if (PyUnicode_Check(object))
99 {
100 bytes = PyUnicode_AsEncodedString(object, (char *)ENC_OPT, NULL);
101 if (bytes == NULL)
102 return NULL;
103
104 if(PyString_AsStringAndSize(bytes, (char **) &p, NULL) == -1)
105 return NULL;
106 if (p == NULL)
107 return NULL;
108
109 *todecref = bytes;
110 }
111 else
112 {
113 PyErr_SetString(PyExc_TypeError, _("object must be string"));
114 return NULL;
115 }
116
117 return (char_u *) p;
118}
119
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200120/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200121 */
122
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200123/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200124typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200125
126static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200127
128typedef struct
129{
130 PyObject_HEAD
131 long softspace;
132 long error;
133} OutputObject;
134
Bram Moolenaar77045652012-09-21 13:46:06 +0200135 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200136OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +0200137{
138 if (val == NULL)
139 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200140 PyErr_SetString(PyExc_AttributeError,
141 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200142 return -1;
143 }
144
145 if (strcmp(name, "softspace") == 0)
146 {
147 if (!PyInt_Check(val))
148 {
149 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
150 return -1;
151 }
152
Bram Moolenaard6e39182013-05-21 18:30:34 +0200153 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +0200154 return 0;
155 }
156
157 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
158 return -1;
159}
160
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200161/* Buffer IO, we write one whole line at a time. */
162static garray_T io_ga = {0, 0, 1, 80, NULL};
163static writefn old_fn = NULL;
164
165 static void
166PythonIO_Flush(void)
167{
168 if (old_fn != NULL && io_ga.ga_len > 0)
169 {
170 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
171 old_fn((char_u *)io_ga.ga_data);
172 }
173 io_ga.ga_len = 0;
174}
175
176 static void
177writer(writefn fn, char_u *str, PyInt n)
178{
179 char_u *ptr;
180
181 /* Flush when switching output function. */
182 if (fn != old_fn)
183 PythonIO_Flush();
184 old_fn = fn;
185
186 /* Write each NL separated line. Text after the last NL is kept for
187 * writing later. */
188 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
189 {
190 PyInt len = ptr - str;
191
192 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
193 break;
194
195 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
196 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
197 fn((char_u *)io_ga.ga_data);
198 str = ptr + 1;
199 n -= len + 1;
200 io_ga.ga_len = 0;
201 }
202
203 /* Put the remaining text into io_ga for later printing. */
204 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
205 {
206 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
207 io_ga.ga_len += (int)n;
208 }
209}
210
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200211 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200212OutputWrite(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200213{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200214 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200215 char *str = NULL;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200216 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200217
Bram Moolenaar27564802011-09-07 19:30:21 +0200218 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200219 return NULL;
220
221 Py_BEGIN_ALLOW_THREADS
222 Python_Lock_Vim();
223 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
224 Python_Release_Vim();
225 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200226 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200227
228 Py_INCREF(Py_None);
229 return Py_None;
230}
231
232 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200233OutputWritelines(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200234{
235 PyInt n;
236 PyInt i;
237 PyObject *list;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200238 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200239
240 if (!PyArg_ParseTuple(args, "O", &list))
241 return NULL;
242 Py_INCREF(list);
243
Bram Moolenaardb913952012-06-29 12:54:53 +0200244 if (!PyList_Check(list))
245 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200246 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
247 Py_DECREF(list);
248 return NULL;
249 }
250
251 n = PyList_Size(list);
252
253 for (i = 0; i < n; ++i)
254 {
255 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200256 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200257 PyInt len;
258
Bram Moolenaardb913952012-06-29 12:54:53 +0200259 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
260 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200261 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
262 Py_DECREF(list);
263 return NULL;
264 }
265
266 Py_BEGIN_ALLOW_THREADS
267 Python_Lock_Vim();
268 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
269 Python_Release_Vim();
270 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200271 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200272 }
273
274 Py_DECREF(list);
275 Py_INCREF(Py_None);
276 return Py_None;
277}
278
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100279 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200280OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100281{
282 /* do nothing */
283 Py_INCREF(Py_None);
284 return Py_None;
285}
286
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200287/***************/
288
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200289static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200290 /* name, function, calling, doc */
291 {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
292 {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
293 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
294 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200295};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200296
297static OutputObject Output =
298{
299 PyObject_HEAD_INIT(&OutputType)
300 0,
301 0
302};
303
304static OutputObject Error =
305{
306 PyObject_HEAD_INIT(&OutputType)
307 0,
308 1
309};
310
311 static int
312PythonIO_Init_io(void)
313{
314 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
315 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
316
317 if (PyErr_Occurred())
318 {
319 EMSG(_("E264: Python: Error initialising I/O objects"));
320 return -1;
321 }
322
323 return 0;
324}
325
326
327static PyObject *VimError;
328
329/* Check to see whether a Vim error has been reported, or a keyboard
330 * interrupt has been detected.
331 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200332
333 static void
334VimTryStart(void)
335{
336 ++trylevel;
337}
338
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200339 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200340VimTryEnd(void)
341{
342 --trylevel;
343 if (got_int)
344 {
345 PyErr_SetNone(PyExc_KeyboardInterrupt);
346 return 1;
347 }
348 else if (!did_throw)
349 return 0;
350 else if (PyErr_Occurred())
351 return 1;
352 else
353 {
354 PyErr_SetVim((char *) current_exception->value);
355 discard_current_exception();
356 return 1;
357 }
358}
359
360 static int
361VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200362{
363 if (got_int)
364 {
365 PyErr_SetNone(PyExc_KeyboardInterrupt);
366 return 1;
367 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200368 return 0;
369}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200370
371/* Vim module - Implementation
372 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200373
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200374 static PyObject *
375VimCommand(PyObject *self UNUSED, PyObject *args)
376{
377 char *cmd;
378 PyObject *result;
379
380 if (!PyArg_ParseTuple(args, "s", &cmd))
381 return NULL;
382
383 PyErr_Clear();
384
385 Py_BEGIN_ALLOW_THREADS
386 Python_Lock_Vim();
387
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200388 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200389 do_cmdline_cmd((char_u *)cmd);
390 update_screen(VALID);
391
392 Python_Release_Vim();
393 Py_END_ALLOW_THREADS
394
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200395 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200396 result = NULL;
397 else
398 result = Py_None;
399
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200400
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200401 Py_XINCREF(result);
402 return result;
403}
404
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200405/*
406 * Function to translate a typval_T into a PyObject; this will recursively
407 * translate lists/dictionaries into their Python equivalents.
408 *
409 * The depth parameter is to avoid infinite recursion, set it to 1 when
410 * you call VimToPython.
411 */
412 static PyObject *
413VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
414{
415 PyObject *result;
416 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200417 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200418
419 /* Avoid infinite recursion */
420 if (depth > 100)
421 {
422 Py_INCREF(Py_None);
423 result = Py_None;
424 return result;
425 }
426
427 /* Check if we run into a recursive loop. The item must be in lookupDict
428 * then and we can use it again. */
429 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
430 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
431 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200432 sprintf(ptrBuf, "%p",
433 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
434 : (void *)our_tv->vval.v_dict);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200435 result = PyDict_GetItemString(lookupDict, ptrBuf);
436 if (result != NULL)
437 {
438 Py_INCREF(result);
439 return result;
440 }
441 }
442
443 if (our_tv->v_type == VAR_STRING)
444 {
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200445 result = Py_BuildValue("s", our_tv->vval.v_string == NULL
446 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200447 }
448 else if (our_tv->v_type == VAR_NUMBER)
449 {
450 char buf[NUMBUFLEN];
451
452 /* For backwards compatibility numbers are stored as strings. */
453 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
454 result = Py_BuildValue("s", buf);
455 }
456# ifdef FEAT_FLOAT
457 else if (our_tv->v_type == VAR_FLOAT)
458 {
459 char buf[NUMBUFLEN];
460
461 sprintf(buf, "%f", our_tv->vval.v_float);
462 result = Py_BuildValue("s", buf);
463 }
464# endif
465 else if (our_tv->v_type == VAR_LIST)
466 {
467 list_T *list = our_tv->vval.v_list;
468 listitem_T *curr;
469
470 result = PyList_New(0);
471
472 if (list != NULL)
473 {
474 PyDict_SetItemString(lookupDict, ptrBuf, result);
475
476 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
477 {
478 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
479 PyList_Append(result, newObj);
480 Py_DECREF(newObj);
481 }
482 }
483 }
484 else if (our_tv->v_type == VAR_DICT)
485 {
486 result = PyDict_New();
487
488 if (our_tv->vval.v_dict != NULL)
489 {
490 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
491 long_u todo = ht->ht_used;
492 hashitem_T *hi;
493 dictitem_T *di;
494
495 PyDict_SetItemString(lookupDict, ptrBuf, result);
496
497 for (hi = ht->ht_array; todo > 0; ++hi)
498 {
499 if (!HASHITEM_EMPTY(hi))
500 {
501 --todo;
502
503 di = dict_lookup(hi);
504 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
505 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
506 Py_DECREF(newObj);
507 }
508 }
509 }
510 }
511 else
512 {
513 Py_INCREF(Py_None);
514 result = Py_None;
515 }
516
517 return result;
518}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200519
520 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200521VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200522{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200523 char *expr;
524 typval_T *our_tv;
525 PyObject *result;
526 PyObject *lookup_dict;
527
528 if (!PyArg_ParseTuple(args, "s", &expr))
529 return NULL;
530
531 Py_BEGIN_ALLOW_THREADS
532 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200533 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200534 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200535 Python_Release_Vim();
536 Py_END_ALLOW_THREADS
537
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200538 if (VimTryEnd())
539 return NULL;
540
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200541 if (our_tv == NULL)
542 {
543 PyErr_SetVim(_("invalid expression"));
544 return NULL;
545 }
546
547 /* Convert the Vim type into a Python type. Create a dictionary that's
548 * used to check for recursive loops. */
549 lookup_dict = PyDict_New();
550 result = VimToPython(our_tv, 1, lookup_dict);
551 Py_DECREF(lookup_dict);
552
553
554 Py_BEGIN_ALLOW_THREADS
555 Python_Lock_Vim();
556 free_tv(our_tv);
557 Python_Release_Vim();
558 Py_END_ALLOW_THREADS
559
560 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200561}
562
Bram Moolenaardb913952012-06-29 12:54:53 +0200563static PyObject *ConvertToPyObject(typval_T *);
564
565 static PyObject *
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200566VimEvalPy(PyObject *self UNUSED, PyObject *args)
Bram Moolenaardb913952012-06-29 12:54:53 +0200567{
Bram Moolenaardb913952012-06-29 12:54:53 +0200568 char *expr;
569 typval_T *our_tv;
570 PyObject *result;
571
572 if (!PyArg_ParseTuple(args, "s", &expr))
573 return NULL;
574
575 Py_BEGIN_ALLOW_THREADS
576 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200577 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +0200578 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200579 Python_Release_Vim();
580 Py_END_ALLOW_THREADS
581
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200582 if (VimTryEnd())
583 return NULL;
584
Bram Moolenaardb913952012-06-29 12:54:53 +0200585 if (our_tv == NULL)
586 {
587 PyErr_SetVim(_("invalid expression"));
588 return NULL;
589 }
590
591 result = ConvertToPyObject(our_tv);
592 Py_BEGIN_ALLOW_THREADS
593 Python_Lock_Vim();
594 free_tv(our_tv);
595 Python_Release_Vim();
596 Py_END_ALLOW_THREADS
597
598 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200599}
600
601 static PyObject *
602VimStrwidth(PyObject *self UNUSED, PyObject *args)
603{
604 char *expr;
605
606 if (!PyArg_ParseTuple(args, "s", &expr))
607 return NULL;
608
Bram Moolenaara54bf402012-12-05 16:30:07 +0100609 return PyLong_FromLong(
610#ifdef FEAT_MBYTE
611 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
612#else
613 STRLEN(expr)
614#endif
615 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200616}
617
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200618/*
619 * Vim module - Definitions
620 */
621
622static struct PyMethodDef VimMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200623 /* name, function, calling, documentation */
624 {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
625 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
626 {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
627 {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
628 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200629};
630
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200631/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200632 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200633 */
634
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200635static PyTypeObject IterType;
636
637typedef PyObject *(*nextfun)(void **);
638typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200639typedef int (*traversefun)(void *, visitproc, void *);
640typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200641
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200642/* Main purpose of this object is removing the need for do python
643 * initialization (i.e. PyType_Ready and setting type attributes) for a big
644 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200645
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200646typedef struct
647{
648 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200649 void *cur;
650 nextfun next;
651 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200652 traversefun traverse;
653 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200654} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200655
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200656 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200657IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
658 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200659{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200660 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200661
Bram Moolenaar774267b2013-05-21 20:51:59 +0200662 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200663 self->cur = start;
664 self->next = next;
665 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200666 self->traverse = traverse;
667 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200668
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200669 return (PyObject *)(self);
670}
671
672 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200673IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200674{
Bram Moolenaar774267b2013-05-21 20:51:59 +0200675 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +0200676 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +0200677 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200678}
679
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200680 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200681IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200682{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200683 if (self->traverse != NULL)
684 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200685 else
686 return 0;
687}
688
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200689/* Mac OSX defines clear() somewhere. */
690#ifdef clear
691# undef clear
692#endif
693
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200694 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200695IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200696{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200697 if (self->clear != NULL)
698 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200699 else
700 return 0;
701}
702
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200703 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200704IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200705{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200706 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200707}
708
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200709 static PyObject *
710IterIter(PyObject *self)
711{
712 return self;
713}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200714
Bram Moolenaardb913952012-06-29 12:54:53 +0200715typedef struct pylinkedlist_S {
716 struct pylinkedlist_S *pll_next;
717 struct pylinkedlist_S *pll_prev;
718 PyObject *pll_obj;
719} pylinkedlist_T;
720
721static pylinkedlist_T *lastdict = NULL;
722static pylinkedlist_T *lastlist = NULL;
723
724 static void
725pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
726{
727 if (ref->pll_prev == NULL)
728 {
729 if (ref->pll_next == NULL)
730 {
731 *last = NULL;
732 return;
733 }
734 }
735 else
736 ref->pll_prev->pll_next = ref->pll_next;
737
738 if (ref->pll_next == NULL)
739 *last = ref->pll_prev;
740 else
741 ref->pll_next->pll_prev = ref->pll_prev;
742}
743
744 static void
745pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
746{
747 if (*last == NULL)
748 ref->pll_prev = NULL;
749 else
750 {
751 (*last)->pll_next = ref;
752 ref->pll_prev = *last;
753 }
754 ref->pll_next = NULL;
755 ref->pll_obj = self;
756 *last = ref;
757}
758
759static PyTypeObject DictionaryType;
760
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200761#define DICTKEY_GET_NOTEMPTY(err) \
762 DICTKEY_GET(err) \
763 if (*key == NUL) \
764 { \
765 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
766 return err; \
767 }
768
Bram Moolenaardb913952012-06-29 12:54:53 +0200769typedef struct
770{
771 PyObject_HEAD
772 dict_T *dict;
773 pylinkedlist_T ref;
774} DictionaryObject;
775
776 static PyObject *
777DictionaryNew(dict_T *dict)
778{
779 DictionaryObject *self;
780
781 self = PyObject_NEW(DictionaryObject, &DictionaryType);
782 if (self == NULL)
783 return NULL;
784 self->dict = dict;
785 ++dict->dv_refcount;
786
787 pyll_add((PyObject *)(self), &self->ref, &lastdict);
788
789 return (PyObject *)(self);
790}
791
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200792 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200793DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200794{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200795 pyll_remove(&self->ref, &lastdict);
796 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200797
798 DESTRUCTOR_FINISH(self);
799}
800
Bram Moolenaardb913952012-06-29 12:54:53 +0200801 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200802DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200803{
804 if (val == NULL)
805 {
806 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
807 return -1;
808 }
809
810 if (strcmp(name, "locked") == 0)
811 {
Bram Moolenaard6e39182013-05-21 18:30:34 +0200812 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200813 {
814 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
815 return -1;
816 }
817 else
818 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200819 int istrue = PyObject_IsTrue(val);
820 if (istrue == -1)
821 return -1;
822 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +0200823 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200824 else
Bram Moolenaard6e39182013-05-21 18:30:34 +0200825 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200826 }
827 return 0;
828 }
829 else
830 {
831 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
832 return -1;
833 }
834}
835
836 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200837DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200838{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200839 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +0200840}
841
842 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200843DictionaryItem(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200844{
845 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200846 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200847 DICTKEY_DECL
848
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200849 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200850
Bram Moolenaard6e39182013-05-21 18:30:34 +0200851 di = dict_find(self->dict, key, -1);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200852
Bram Moolenaar696c2112012-09-21 13:43:14 +0200853 DICTKEY_UNREF
854
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200855 if (di == NULL)
856 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200857 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200858 return NULL;
859 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200860
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200861 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200862}
863
864 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200865DictionaryAssItem(DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200866{
867 char_u *key;
868 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200869 dict_T *d = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200870 dictitem_T *di;
871 DICTKEY_DECL
872
873 if (d->dv_lock)
874 {
875 PyErr_SetVim(_("dict is locked"));
876 return -1;
877 }
878
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200879 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200880
881 di = dict_find(d, key, -1);
882
883 if (valObject == NULL)
884 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200885 hashitem_T *hi;
886
Bram Moolenaardb913952012-06-29 12:54:53 +0200887 if (di == NULL)
888 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200889 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200890 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +0200891 return -1;
892 }
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200893 hi = hash_find(&d->dv_hashtab, di->di_key);
Bram Moolenaardb913952012-06-29 12:54:53 +0200894 hash_remove(&d->dv_hashtab, hi);
895 dictitem_free(di);
896 return 0;
897 }
898
899 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200900 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +0200901
902 if (di == NULL)
903 {
904 di = dictitem_alloc(key);
905 if (di == NULL)
906 {
907 PyErr_NoMemory();
908 return -1;
909 }
910 di->di_tv.v_lock = 0;
911
912 if (dict_add(d, di) == FAIL)
913 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200914 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +0200915 vim_free(di);
916 PyErr_SetVim(_("failed to add key to dictionary"));
917 return -1;
918 }
919 }
920 else
921 clear_tv(&di->di_tv);
922
923 DICTKEY_UNREF
924
925 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +0200926 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200927 return 0;
928}
929
930 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200931DictionaryListKeys(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200932{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200933 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200934 long_u todo = dict->dv_hashtab.ht_used;
935 Py_ssize_t i = 0;
936 PyObject *r;
937 hashitem_T *hi;
938
939 r = PyList_New(todo);
940 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
941 {
942 if (!HASHITEM_EMPTY(hi))
943 {
944 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
945 --todo;
946 ++i;
947 }
948 }
949 return r;
950}
951
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200952static PyMappingMethods DictionaryAsMapping = {
953 (lenfunc) DictionaryLength,
954 (binaryfunc) DictionaryItem,
955 (objobjargproc) DictionaryAssItem,
956};
957
Bram Moolenaardb913952012-06-29 12:54:53 +0200958static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200959 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
960 { NULL, NULL, 0, NULL }
Bram Moolenaardb913952012-06-29 12:54:53 +0200961};
962
963static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200964static PySequenceMethods ListAsSeq;
965static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +0200966
967typedef struct
968{
969 PyObject_HEAD
970 list_T *list;
971 pylinkedlist_T ref;
972} ListObject;
973
974 static PyObject *
975ListNew(list_T *list)
976{
977 ListObject *self;
978
979 self = PyObject_NEW(ListObject, &ListType);
980 if (self == NULL)
981 return NULL;
982 self->list = list;
983 ++list->lv_refcount;
984
985 pyll_add((PyObject *)(self), &self->ref, &lastlist);
986
987 return (PyObject *)(self);
988}
989
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200990 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200991ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200992{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200993 pyll_remove(&self->ref, &lastlist);
994 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200995
996 DESTRUCTOR_FINISH(self);
997}
998
Bram Moolenaardb913952012-06-29 12:54:53 +0200999 static int
1000list_py_concat(list_T *l, PyObject *obj, PyObject *lookupDict)
1001{
1002 Py_ssize_t i;
1003 Py_ssize_t lsize = PySequence_Size(obj);
1004 PyObject *litem;
1005 listitem_T *li;
1006
1007 for(i=0; i<lsize; i++)
1008 {
1009 li = listitem_alloc();
1010 if (li == NULL)
1011 {
1012 PyErr_NoMemory();
1013 return -1;
1014 }
1015 li->li_tv.v_lock = 0;
1016
1017 litem = PySequence_GetItem(obj, i);
1018 if (litem == NULL)
1019 return -1;
1020 if (_ConvertFromPyObject(litem, &li->li_tv, lookupDict) == -1)
1021 return -1;
1022
1023 list_append(l, li);
1024 }
1025 return 0;
1026}
1027
Bram Moolenaardb913952012-06-29 12:54:53 +02001028 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001029ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001030{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001031 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02001032}
1033
1034 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001035ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02001036{
1037 listitem_T *li;
1038
Bram Moolenaard6e39182013-05-21 18:30:34 +02001039 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02001040 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001041 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001042 return NULL;
1043 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02001044 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02001045 if (li == NULL)
1046 {
1047 PyErr_SetVim(_("internal error: failed to get vim list item"));
1048 return NULL;
1049 }
1050 return ConvertToPyObject(&li->li_tv);
1051}
1052
1053#define PROC_RANGE \
1054 if (last < 0) {\
1055 if (last < -size) \
1056 last = 0; \
1057 else \
1058 last += size; \
1059 } \
1060 if (first < 0) \
1061 first = 0; \
1062 if (first > size) \
1063 first = size; \
1064 if (last > size) \
1065 last = size;
1066
1067 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001068ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02001069{
1070 PyInt i;
1071 PyInt size = ListLength(self);
1072 PyInt n;
1073 PyObject *list;
1074 int reversed = 0;
1075
1076 PROC_RANGE
1077 if (first >= last)
1078 first = last;
1079
1080 n = last-first;
1081 list = PyList_New(n);
1082 if (list == NULL)
1083 return NULL;
1084
1085 for (i = 0; i < n; ++i)
1086 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02001087 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02001088 if (item == NULL)
1089 {
1090 Py_DECREF(list);
1091 return NULL;
1092 }
1093
1094 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1095 {
1096 Py_DECREF(item);
1097 Py_DECREF(list);
1098 return NULL;
1099 }
1100 }
1101
1102 return list;
1103}
1104
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001105typedef struct
1106{
1107 listwatch_T lw;
1108 list_T *list;
1109} listiterinfo_T;
1110
1111 static void
1112ListIterDestruct(listiterinfo_T *lii)
1113{
1114 list_rem_watch(lii->list, &lii->lw);
1115 PyMem_Free(lii);
1116}
1117
1118 static PyObject *
1119ListIterNext(listiterinfo_T **lii)
1120{
1121 PyObject *r;
1122
1123 if (!((*lii)->lw.lw_item))
1124 return NULL;
1125
1126 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1127 return NULL;
1128
1129 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1130
1131 return r;
1132}
1133
1134 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001135ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001136{
1137 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001138 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001139
1140 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1141 {
1142 PyErr_NoMemory();
1143 return NULL;
1144 }
1145
1146 list_add_watch(l, &lii->lw);
1147 lii->lw.lw_item = l->lv_first;
1148 lii->list = l;
1149
1150 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001151 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
1152 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001153}
1154
Bram Moolenaardb913952012-06-29 12:54:53 +02001155 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001156ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001157{
1158 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001159 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001160 listitem_T *li;
1161 Py_ssize_t length = ListLength(self);
1162
1163 if (l->lv_lock)
1164 {
1165 PyErr_SetVim(_("list is locked"));
1166 return -1;
1167 }
1168 if (index>length || (index==length && obj==NULL))
1169 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001170 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001171 return -1;
1172 }
1173
1174 if (obj == NULL)
1175 {
1176 li = list_find(l, (long) index);
1177 list_remove(l, li, li);
1178 clear_tv(&li->li_tv);
1179 vim_free(li);
1180 return 0;
1181 }
1182
1183 if (ConvertFromPyObject(obj, &tv) == -1)
1184 return -1;
1185
1186 if (index == length)
1187 {
1188 if (list_append_tv(l, &tv) == FAIL)
1189 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001190 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001191 PyErr_SetVim(_("Failed to add item to list"));
1192 return -1;
1193 }
1194 }
1195 else
1196 {
1197 li = list_find(l, (long) index);
1198 clear_tv(&li->li_tv);
1199 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001200 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001201 }
1202 return 0;
1203}
1204
1205 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001206ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001207{
1208 PyInt size = ListLength(self);
1209 Py_ssize_t i;
1210 Py_ssize_t lsize;
1211 PyObject *litem;
1212 listitem_T *li;
1213 listitem_T *next;
1214 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001215 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001216
1217 if (l->lv_lock)
1218 {
1219 PyErr_SetVim(_("list is locked"));
1220 return -1;
1221 }
1222
1223 PROC_RANGE
1224
1225 if (first == size)
1226 li = NULL;
1227 else
1228 {
1229 li = list_find(l, (long) first);
1230 if (li == NULL)
1231 {
1232 PyErr_SetVim(_("internal error: no vim list item"));
1233 return -1;
1234 }
1235 if (last > first)
1236 {
1237 i = last - first;
1238 while (i-- && li != NULL)
1239 {
1240 next = li->li_next;
1241 listitem_remove(l, li);
1242 li = next;
1243 }
1244 }
1245 }
1246
1247 if (obj == NULL)
1248 return 0;
1249
1250 if (!PyList_Check(obj))
1251 {
1252 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1253 return -1;
1254 }
1255
1256 lsize = PyList_Size(obj);
1257
1258 for(i=0; i<lsize; i++)
1259 {
1260 litem = PyList_GetItem(obj, i);
1261 if (litem == NULL)
1262 return -1;
1263 if (ConvertFromPyObject(litem, &v) == -1)
1264 return -1;
1265 if (list_insert_tv(l, &v, li) == FAIL)
1266 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001267 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001268 PyErr_SetVim(_("internal error: failed to add item to list"));
1269 return -1;
1270 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001271 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001272 }
1273 return 0;
1274}
1275
1276 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001277ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001278{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001279 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001280 PyObject *lookup_dict;
1281
1282 if (l->lv_lock)
1283 {
1284 PyErr_SetVim(_("list is locked"));
1285 return NULL;
1286 }
1287
1288 if (!PySequence_Check(obj))
1289 {
1290 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1291 return NULL;
1292 }
1293
1294 lookup_dict = PyDict_New();
1295 if (list_py_concat(l, obj, lookup_dict) == -1)
1296 {
1297 Py_DECREF(lookup_dict);
1298 return NULL;
1299 }
1300 Py_DECREF(lookup_dict);
1301
1302 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02001303 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02001304}
1305
Bram Moolenaar66b79852012-09-21 14:00:35 +02001306 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001307ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001308{
1309 if (val == NULL)
1310 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001311 PyErr_SetString(PyExc_AttributeError,
1312 _("cannot delete vim.dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001313 return -1;
1314 }
1315
1316 if (strcmp(name, "locked") == 0)
1317 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001318 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001319 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001320 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001321 return -1;
1322 }
1323 else
1324 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001325 int istrue = PyObject_IsTrue(val);
1326 if (istrue == -1)
1327 return -1;
1328 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001329 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001330 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001331 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001332 }
1333 return 0;
1334 }
1335 else
1336 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001337 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001338 return -1;
1339 }
1340}
1341
Bram Moolenaardb913952012-06-29 12:54:53 +02001342static struct PyMethodDef ListMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001343 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1344 { NULL, NULL, 0, NULL }
Bram Moolenaardb913952012-06-29 12:54:53 +02001345};
1346
1347typedef struct
1348{
1349 PyObject_HEAD
1350 char_u *name;
1351} FunctionObject;
1352
1353static PyTypeObject FunctionType;
1354
1355 static PyObject *
1356FunctionNew(char_u *name)
1357{
1358 FunctionObject *self;
1359
1360 self = PyObject_NEW(FunctionObject, &FunctionType);
1361 if (self == NULL)
1362 return NULL;
1363 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1364 if (self->name == NULL)
1365 {
1366 PyErr_NoMemory();
1367 return NULL;
1368 }
1369 STRCPY(self->name, name);
1370 func_ref(name);
1371 return (PyObject *)(self);
1372}
1373
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001374 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001375FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001376{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001377 func_unref(self->name);
1378 PyMem_Free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001379
1380 DESTRUCTOR_FINISH(self);
1381}
1382
Bram Moolenaardb913952012-06-29 12:54:53 +02001383 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001384FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02001385{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001386 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02001387 typval_T args;
1388 typval_T selfdicttv;
1389 typval_T rettv;
1390 dict_T *selfdict = NULL;
1391 PyObject *selfdictObject;
1392 PyObject *result;
1393 int error;
1394
1395 if (ConvertFromPyObject(argsObject, &args) == -1)
1396 return NULL;
1397
1398 if (kwargs != NULL)
1399 {
1400 selfdictObject = PyDict_GetItemString(kwargs, "self");
1401 if (selfdictObject != NULL)
1402 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001403 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001404 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001405 PyErr_SetString(PyExc_TypeError,
1406 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001407 clear_tv(&args);
1408 return NULL;
1409 }
1410 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001411 {
1412 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02001413 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001414 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001415 selfdict = selfdicttv.vval.v_dict;
1416 }
1417 }
1418
Bram Moolenaar71700b82013-05-15 17:49:05 +02001419 Py_BEGIN_ALLOW_THREADS
1420 Python_Lock_Vim();
1421
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001422 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02001423 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02001424
1425 Python_Release_Vim();
1426 Py_END_ALLOW_THREADS
1427
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001428 if (VimTryEnd())
1429 result = NULL;
1430 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02001431 {
1432 result = NULL;
1433 PyErr_SetVim(_("failed to run function"));
1434 }
1435 else
1436 result = ConvertToPyObject(&rettv);
1437
Bram Moolenaardb913952012-06-29 12:54:53 +02001438 clear_tv(&args);
1439 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001440 if (selfdict != NULL)
1441 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001442
1443 return result;
1444}
1445
1446static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001447 {"__call__", (PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1448 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001449};
1450
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001451/*
1452 * Options object
1453 */
1454
1455static PyTypeObject OptionsType;
1456
1457typedef int (*checkfun)(void *);
1458
1459typedef struct
1460{
1461 PyObject_HEAD
1462 int opt_type;
1463 void *from;
1464 checkfun Check;
1465 PyObject *fromObj;
1466} OptionsObject;
1467
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001468 static int
1469dummy_check(void *arg UNUSED)
1470{
1471 return 0;
1472}
1473
1474 static PyObject *
1475OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1476{
1477 OptionsObject *self;
1478
Bram Moolenaar774267b2013-05-21 20:51:59 +02001479 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001480 if (self == NULL)
1481 return NULL;
1482
1483 self->opt_type = opt_type;
1484 self->from = from;
1485 self->Check = Check;
1486 self->fromObj = fromObj;
1487 if (fromObj)
1488 Py_INCREF(fromObj);
1489
1490 return (PyObject *)(self);
1491}
1492
1493 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001494OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001495{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001496 PyObject_GC_UnTrack((void *)(self));
1497 Py_XDECREF(self->fromObj);
1498 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001499}
1500
1501 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001502OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001503{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001504 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001505 return 0;
1506}
1507
1508 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001509OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001510{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001511 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001512 return 0;
1513}
1514
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001515 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001516OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001517{
1518 char_u *key;
1519 int flags;
1520 long numval;
1521 char_u *stringval;
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 NULL;
1526
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001527 DICTKEY_GET_NOTEMPTY(NULL)
1528
1529 flags = get_option_value_strict(key, &numval, &stringval,
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 NULL;
1538 }
1539
1540 if (flags & SOPT_UNSET)
1541 {
1542 Py_INCREF(Py_None);
1543 return Py_None;
1544 }
1545 else if (flags & SOPT_BOOL)
1546 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001547 PyObject *r;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001548 r = numval ? Py_True : Py_False;
1549 Py_INCREF(r);
1550 return r;
1551 }
1552 else if (flags & SOPT_NUM)
1553 return PyInt_FromLong(numval);
1554 else if (flags & SOPT_STRING)
1555 {
1556 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001557 {
1558 PyObject *r = PyBytes_FromString((char *) stringval);
1559 vim_free(stringval);
1560 return r;
1561 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001562 else
1563 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001564 PyErr_SetString(PyExc_RuntimeError,
1565 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001566 return NULL;
1567 }
1568 }
1569 else
1570 {
1571 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1572 return NULL;
1573 }
1574}
1575
1576 static int
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001577set_option_value_err(key, numval, stringval, opt_flags)
1578 char_u *key;
1579 int numval;
1580 char_u *stringval;
1581 int opt_flags;
1582{
1583 char_u *errmsg;
1584
1585 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
1586 {
1587 if (VimTryEnd())
1588 return FAIL;
1589 PyErr_SetVim((char *)errmsg);
1590 return FAIL;
1591 }
1592 return OK;
1593}
1594
1595 static int
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001596set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1597 char_u *key;
1598 int numval;
1599 char_u *stringval;
1600 int opt_flags;
1601 int opt_type;
1602 void *from;
1603{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001604 win_T *save_curwin = NULL;
1605 tabpage_T *save_curtab = NULL;
1606 buf_T *save_curbuf = NULL;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001607 int r = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001608
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001609 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001610 switch (opt_type)
1611 {
1612 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001613 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
1614 win_find_tabpage((win_T *)from)) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001615 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001616 if (VimTryEnd())
1617 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001618 PyErr_SetVim("Problem while switching windows.");
1619 return -1;
1620 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001621 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001622 restore_win(save_curwin, save_curtab);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001623 if (r == FAIL)
1624 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001625 break;
1626 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001627 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001628 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02001629 restore_buffer(save_curbuf);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001630 if (r == FAIL)
1631 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001632 break;
1633 case SREQ_GLOBAL:
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001634 r = set_option_value_err(key, numval, stringval, opt_flags);
1635 if (r == FAIL)
1636 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001637 break;
1638 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001639 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001640}
1641
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001642 static void *
1643py_memsave(void *p, size_t len)
1644{
1645 void *r;
1646 if (!(r = PyMem_Malloc(len)))
1647 return NULL;
1648 mch_memmove(r, p, len);
1649 return r;
1650}
1651
1652#define PY_STRSAVE(s) ((char_u *) py_memsave(s, STRLEN(s) + 1))
1653
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001654 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001655OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001656{
1657 char_u *key;
1658 int flags;
1659 int opt_flags;
1660 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001661 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001662
Bram Moolenaard6e39182013-05-21 18:30:34 +02001663 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001664 return -1;
1665
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001666 DICTKEY_GET_NOTEMPTY(-1)
1667
1668 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001669 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001670
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001671 if (flags == 0)
1672 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001673 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001674 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001675 return -1;
1676 }
1677
1678 if (valObject == NULL)
1679 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001680 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001681 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001682 PyErr_SetString(PyExc_ValueError,
1683 _("unable to unset global option"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001684 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001685 return -1;
1686 }
1687 else if (!(flags & SOPT_GLOBAL))
1688 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001689 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
1690 "without global value"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001691 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001692 return -1;
1693 }
1694 else
1695 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001696 unset_global_local_option(key, self->from);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001697 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001698 return 0;
1699 }
1700 }
1701
Bram Moolenaard6e39182013-05-21 18:30:34 +02001702 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001703
1704 if (flags & SOPT_BOOL)
1705 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001706 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001707
Bram Moolenaarb983f752013-05-15 16:11:50 +02001708 if (istrue == -1)
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001709 r = -1;
1710 else
1711 r = set_option_value_for(key, istrue, NULL,
1712 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001713 }
1714 else if (flags & SOPT_NUM)
1715 {
1716 int val;
1717
1718#if PY_MAJOR_VERSION < 3
1719 if (PyInt_Check(valObject))
1720 val = PyInt_AsLong(valObject);
1721 else
1722#endif
1723 if (PyLong_Check(valObject))
1724 val = PyLong_AsLong(valObject);
1725 else
1726 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001727 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001728 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001729 return -1;
1730 }
1731
1732 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001733 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001734 }
1735 else
1736 {
1737 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001738 PyObject *todecref;
1739
1740 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001741 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001742 r = set_option_value_for(key, 0, val, opt_flags,
1743 self->opt_type, self->from);
1744 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001745 }
1746 else
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001747 r = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001748 }
1749
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001750 DICTKEY_UNREF
1751
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001752 return r;
1753}
1754
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001755static PyMappingMethods OptionsAsMapping = {
1756 (lenfunc) NULL,
1757 (binaryfunc) OptionsItem,
1758 (objobjargproc) OptionsAssItem,
1759};
1760
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001761/* Tabpage object
1762 */
1763
1764typedef struct
1765{
1766 PyObject_HEAD
1767 tabpage_T *tab;
1768} TabPageObject;
1769
1770static PyObject *WinListNew(TabPageObject *tabObject);
1771
1772static PyTypeObject TabPageType;
1773
1774 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001775CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001776{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001777 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001778 {
1779 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1780 return -1;
1781 }
1782
1783 return 0;
1784}
1785
1786 static PyObject *
1787TabPageNew(tabpage_T *tab)
1788{
1789 TabPageObject *self;
1790
1791 if (TAB_PYTHON_REF(tab))
1792 {
1793 self = TAB_PYTHON_REF(tab);
1794 Py_INCREF(self);
1795 }
1796 else
1797 {
1798 self = PyObject_NEW(TabPageObject, &TabPageType);
1799 if (self == NULL)
1800 return NULL;
1801 self->tab = tab;
1802 TAB_PYTHON_REF(tab) = self;
1803 }
1804
1805 return (PyObject *)(self);
1806}
1807
1808 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001809TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001810{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001811 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
1812 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001813
1814 DESTRUCTOR_FINISH(self);
1815}
1816
1817 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02001818TabPageAttrValid(TabPageObject *self, char *name)
1819{
1820 PyObject *r;
1821
1822 if (strcmp(name, "valid") != 0)
1823 return NULL;
1824
1825 r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
1826 Py_INCREF(r);
1827 return r;
1828}
1829
1830 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001831TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001832{
1833 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001834 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001835 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001836 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001837 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001838 return DictionaryNew(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001839 else if (strcmp(name, "window") == 0)
1840 {
1841 /* For current tab window.c does not bother to set or update tp_curwin
1842 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001843 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001844 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001845 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001846 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001847 }
1848 return NULL;
1849}
1850
1851 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001852TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001853{
1854 static char repr[100];
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001855
Bram Moolenaard6e39182013-05-21 18:30:34 +02001856 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001857 {
1858 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
1859 return PyString_FromString(repr);
1860 }
1861 else
1862 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001863 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001864
1865 if (t == 0)
1866 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
1867 (self));
1868 else
1869 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
1870
1871 return PyString_FromString(repr);
1872 }
1873}
1874
1875static struct PyMethodDef TabPageMethods[] = {
1876 /* name, function, calling, documentation */
1877 { NULL, NULL, 0, NULL }
1878};
1879
1880/*
1881 * Window list object
1882 */
1883
1884static PyTypeObject TabListType;
1885static PySequenceMethods TabListAsSeq;
1886
1887typedef struct
1888{
1889 PyObject_HEAD
1890} TabListObject;
1891
1892 static PyInt
1893TabListLength(PyObject *self UNUSED)
1894{
1895 tabpage_T *tp = first_tabpage;
1896 PyInt n = 0;
1897
1898 while (tp != NULL)
1899 {
1900 ++n;
1901 tp = tp->tp_next;
1902 }
1903
1904 return n;
1905}
1906
1907 static PyObject *
1908TabListItem(PyObject *self UNUSED, PyInt n)
1909{
1910 tabpage_T *tp;
1911
1912 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
1913 if (n == 0)
1914 return TabPageNew(tp);
1915
1916 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
1917 return NULL;
1918}
1919
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001920/* Window object
1921 */
1922
1923typedef struct
1924{
1925 PyObject_HEAD
1926 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001927 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001928} WindowObject;
1929
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001930static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001931
1932 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001933CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001934{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001935 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001936 {
1937 PyErr_SetVim(_("attempt to refer to deleted window"));
1938 return -1;
1939 }
1940
1941 return 0;
1942}
1943
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001944 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001945WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02001946{
1947 /* We need to handle deletion of windows underneath us.
1948 * If we add a "w_python*_ref" field to the win_T structure,
1949 * then we can get at it in win_free() in vim. We then
1950 * need to create only ONE Python object per window - if
1951 * we try to create a second, just INCREF the existing one
1952 * and return it. The (single) Python object referring to
1953 * the window is stored in "w_python*_ref".
1954 * On a win_free() we set the Python object's win_T* field
1955 * to an invalid value. We trap all uses of a window
1956 * object, and reject them if the win_T* field is invalid.
1957 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001958 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02001959 * w_python_ref and w_python3_ref fields respectively.
1960 */
1961
1962 WindowObject *self;
1963
1964 if (WIN_PYTHON_REF(win))
1965 {
1966 self = WIN_PYTHON_REF(win);
1967 Py_INCREF(self);
1968 }
1969 else
1970 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02001971 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02001972 if (self == NULL)
1973 return NULL;
1974 self->win = win;
1975 WIN_PYTHON_REF(win) = self;
1976 }
1977
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001978 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
1979
Bram Moolenaar971db462013-05-12 18:44:48 +02001980 return (PyObject *)(self);
1981}
1982
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001983 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001984WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001985{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001986 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001987 if (self->win && self->win != INVALID_WINDOW_VALUE)
1988 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02001989 Py_XDECREF(((PyObject *)(self->tabObject)));
1990 PyObject_GC_Del((void *)(self));
1991}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001992
Bram Moolenaar774267b2013-05-21 20:51:59 +02001993 static int
1994WindowTraverse(WindowObject *self, visitproc visit, void *arg)
1995{
1996 Py_VISIT(((PyObject *)(self->tabObject)));
1997 return 0;
1998}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001999
Bram Moolenaar774267b2013-05-21 20:51:59 +02002000 static int
2001WindowClear(WindowObject *self)
2002{
2003 Py_CLEAR(self->tabObject);
2004 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002005}
2006
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002007 static win_T *
2008get_firstwin(TabPageObject *tabObject)
2009{
2010 if (tabObject)
2011 {
2012 if (CheckTabPage(tabObject))
2013 return NULL;
2014 /* For current tab window.c does not bother to set or update tp_firstwin
2015 */
2016 else if (tabObject->tab == curtab)
2017 return firstwin;
2018 else
2019 return tabObject->tab->tp_firstwin;
2020 }
2021 else
2022 return firstwin;
2023}
2024
Bram Moolenaar971db462013-05-12 18:44:48 +02002025 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002026WindowAttrValid(WindowObject *self, char *name)
2027{
2028 PyObject *r;
2029
2030 if (strcmp(name, "valid") != 0)
2031 return NULL;
2032
2033 r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
2034 Py_INCREF(r);
2035 return r;
2036}
2037
2038 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002039WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002040{
2041 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002042 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002043 else if (strcmp(name, "cursor") == 0)
2044 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002045 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002046
2047 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2048 }
2049 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002050 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002051#ifdef FEAT_WINDOWS
2052 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002053 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002054#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002055#ifdef FEAT_VERTSPLIT
2056 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002057 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002058 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002059 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002060#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02002061 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002062 return DictionaryNew(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002063 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002064 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
2065 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02002066 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002067 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002068 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002069 return NULL;
2070 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002071 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002072 }
2073 else if (strcmp(name, "tabpage") == 0)
2074 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002075 Py_INCREF(self->tabObject);
2076 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002077 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002078 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002079 return Py_BuildValue("[ssssssssss]", "buffer", "cursor", "height",
2080 "vars", "options", "number", "row", "col", "tabpage", "valid");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002081 else
2082 return NULL;
2083}
2084
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002085 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002086WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002087{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002088 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002089 return -1;
2090
2091 if (strcmp(name, "buffer") == 0)
2092 {
2093 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2094 return -1;
2095 }
2096 else if (strcmp(name, "cursor") == 0)
2097 {
2098 long lnum;
2099 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002100
2101 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2102 return -1;
2103
Bram Moolenaard6e39182013-05-21 18:30:34 +02002104 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002105 {
2106 PyErr_SetVim(_("cursor position outside buffer"));
2107 return -1;
2108 }
2109
2110 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002111 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002112 return -1;
2113
Bram Moolenaard6e39182013-05-21 18:30:34 +02002114 self->win->w_cursor.lnum = lnum;
2115 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002116#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02002117 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002118#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002119 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002120 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002121
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002122 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002123 return 0;
2124 }
2125 else if (strcmp(name, "height") == 0)
2126 {
2127 int height;
2128 win_T *savewin;
2129
2130 if (!PyArg_Parse(val, "i", &height))
2131 return -1;
2132
2133#ifdef FEAT_GUI
2134 need_mouse_correct = TRUE;
2135#endif
2136 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002137 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002138
2139 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002140 win_setheight(height);
2141 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002142 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002143 return -1;
2144
2145 return 0;
2146 }
2147#ifdef FEAT_VERTSPLIT
2148 else if (strcmp(name, "width") == 0)
2149 {
2150 int width;
2151 win_T *savewin;
2152
2153 if (!PyArg_Parse(val, "i", &width))
2154 return -1;
2155
2156#ifdef FEAT_GUI
2157 need_mouse_correct = TRUE;
2158#endif
2159 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002160 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002161
2162 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002163 win_setwidth(width);
2164 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002165 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002166 return -1;
2167
2168 return 0;
2169 }
2170#endif
2171 else
2172 {
2173 PyErr_SetString(PyExc_AttributeError, name);
2174 return -1;
2175 }
2176}
2177
2178 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002179WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002180{
2181 static char repr[100];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002182
Bram Moolenaard6e39182013-05-21 18:30:34 +02002183 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002184 {
2185 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2186 return PyString_FromString(repr);
2187 }
2188 else
2189 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002190 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002191
Bram Moolenaar6d216452013-05-12 19:00:41 +02002192 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002193 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2194 (self));
2195 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02002196 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002197
2198 return PyString_FromString(repr);
2199 }
2200}
2201
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002202static struct PyMethodDef WindowMethods[] = {
2203 /* name, function, calling, documentation */
2204 { NULL, NULL, 0, NULL }
2205};
2206
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002207/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002208 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002209 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002210
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002211static PyTypeObject WinListType;
2212static PySequenceMethods WinListAsSeq;
2213
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002214typedef struct
2215{
2216 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002217 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002218} WinListObject;
2219
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002220 static PyObject *
2221WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002222{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002223 WinListObject *self;
2224
2225 self = PyObject_NEW(WinListObject, &WinListType);
2226 self->tabObject = tabObject;
2227 Py_INCREF(tabObject);
2228
2229 return (PyObject *)(self);
2230}
2231
2232 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002233WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002234{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002235 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002236
2237 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02002238 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002239 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02002240 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002241
2242 DESTRUCTOR_FINISH(self);
2243}
2244
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002245 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002246WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002247{
2248 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002249 PyInt n = 0;
2250
Bram Moolenaard6e39182013-05-21 18:30:34 +02002251 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002252 return -1;
2253
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002254 while (w != NULL)
2255 {
2256 ++n;
2257 w = W_NEXT(w);
2258 }
2259
2260 return n;
2261}
2262
2263 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002264WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002265{
2266 win_T *w;
2267
Bram Moolenaard6e39182013-05-21 18:30:34 +02002268 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002269 return NULL;
2270
2271 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002272 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002273 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002274
2275 PyErr_SetString(PyExc_IndexError, _("no such window"));
2276 return NULL;
2277}
2278
2279/* Convert a Python string into a Vim line.
2280 *
2281 * The result is in allocated memory. All internal nulls are replaced by
2282 * newline characters. It is an error for the string to contain newline
2283 * characters.
2284 *
2285 * On errors, the Python exception data is set, and NULL is returned.
2286 */
2287 static char *
2288StringToLine(PyObject *obj)
2289{
2290 const char *str;
2291 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002292 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002293 PyInt len;
2294 PyInt i;
2295 char *p;
2296
2297 if (obj == NULL || !PyString_Check(obj))
2298 {
2299 PyErr_BadArgument();
2300 return NULL;
2301 }
2302
Bram Moolenaar19e60942011-06-19 00:27:51 +02002303 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2304 str = PyString_AsString(bytes);
2305 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002306
2307 /*
2308 * Error checking: String must not contain newlines, as we
2309 * are replacing a single line, and we must replace it with
2310 * a single line.
2311 * A trailing newline is removed, so that append(f.readlines()) works.
2312 */
2313 p = memchr(str, '\n', len);
2314 if (p != NULL)
2315 {
2316 if (p == str + len - 1)
2317 --len;
2318 else
2319 {
2320 PyErr_SetVim(_("string cannot contain newlines"));
2321 return NULL;
2322 }
2323 }
2324
2325 /* Create a copy of the string, with internal nulls replaced by
2326 * newline characters, as is the vim convention.
2327 */
2328 save = (char *)alloc((unsigned)(len+1));
2329 if (save == NULL)
2330 {
2331 PyErr_NoMemory();
2332 return NULL;
2333 }
2334
2335 for (i = 0; i < len; ++i)
2336 {
2337 if (str[i] == '\0')
2338 save[i] = '\n';
2339 else
2340 save[i] = str[i];
2341 }
2342
2343 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002344 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002345
2346 return save;
2347}
2348
2349/* Get a line from the specified buffer. The line number is
2350 * in Vim format (1-based). The line is returned as a Python
2351 * string object.
2352 */
2353 static PyObject *
2354GetBufferLine(buf_T *buf, PyInt n)
2355{
2356 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2357}
2358
2359
2360/* Get a list of lines from the specified buffer. The line numbers
2361 * are in Vim format (1-based). The range is from lo up to, but not
2362 * including, hi. The list is returned as a Python list of string objects.
2363 */
2364 static PyObject *
2365GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2366{
2367 PyInt i;
2368 PyInt n = hi - lo;
2369 PyObject *list = PyList_New(n);
2370
2371 if (list == NULL)
2372 return NULL;
2373
2374 for (i = 0; i < n; ++i)
2375 {
2376 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2377
2378 /* Error check - was the Python string creation OK? */
2379 if (str == NULL)
2380 {
2381 Py_DECREF(list);
2382 return NULL;
2383 }
2384
2385 /* Set the list item */
2386 if (PyList_SetItem(list, i, str))
2387 {
2388 Py_DECREF(str);
2389 Py_DECREF(list);
2390 return NULL;
2391 }
2392 }
2393
2394 /* The ownership of the Python list is passed to the caller (ie,
2395 * the caller should Py_DECREF() the object when it is finished
2396 * with it).
2397 */
2398
2399 return list;
2400}
2401
2402/*
2403 * Check if deleting lines made the cursor position invalid.
2404 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2405 * deleted).
2406 */
2407 static void
2408py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2409{
2410 if (curwin->w_cursor.lnum >= lo)
2411 {
2412 /* Adjust the cursor position if it's in/after the changed
2413 * lines. */
2414 if (curwin->w_cursor.lnum >= hi)
2415 {
2416 curwin->w_cursor.lnum += extra;
2417 check_cursor_col();
2418 }
2419 else if (extra < 0)
2420 {
2421 curwin->w_cursor.lnum = lo;
2422 check_cursor();
2423 }
2424 else
2425 check_cursor_col();
2426 changed_cline_bef_curs();
2427 }
2428 invalidate_botline();
2429}
2430
Bram Moolenaar19e60942011-06-19 00:27:51 +02002431/*
2432 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002433 * in Vim format (1-based). The replacement line is given as
2434 * a Python string object. The object is checked for validity
2435 * and correct format. Errors are returned as a value of FAIL.
2436 * The return value is OK on success.
2437 * If OK is returned and len_change is not NULL, *len_change
2438 * is set to the change in the buffer length.
2439 */
2440 static int
2441SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2442{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002443 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002444 * There are three cases:
2445 * 1. NULL, or None - this is a deletion.
2446 * 2. A string - this is a replacement.
2447 * 3. Anything else - this is an error.
2448 */
2449 if (line == Py_None || line == NULL)
2450 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002451 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002452
2453 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002454 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002455
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002456 VimTryStart();
2457
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002458 if (u_savedel((linenr_T)n, 1L) == FAIL)
2459 PyErr_SetVim(_("cannot save undo information"));
2460 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2461 PyErr_SetVim(_("cannot delete line"));
2462 else
2463 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002464 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002465 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2466 deleted_lines_mark((linenr_T)n, 1L);
2467 }
2468
Bram Moolenaar105bc352013-05-17 16:03:57 +02002469 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002470
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002471 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002472 return FAIL;
2473
2474 if (len_change)
2475 *len_change = -1;
2476
2477 return OK;
2478 }
2479 else if (PyString_Check(line))
2480 {
2481 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002482 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002483
2484 if (save == NULL)
2485 return FAIL;
2486
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002487 VimTryStart();
2488
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002489 /* We do not need to free "save" if ml_replace() consumes it. */
2490 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002491 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002492
2493 if (u_savesub((linenr_T)n) == FAIL)
2494 {
2495 PyErr_SetVim(_("cannot save undo information"));
2496 vim_free(save);
2497 }
2498 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2499 {
2500 PyErr_SetVim(_("cannot replace line"));
2501 vim_free(save);
2502 }
2503 else
2504 changed_bytes((linenr_T)n, 0);
2505
Bram Moolenaar105bc352013-05-17 16:03:57 +02002506 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002507
2508 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02002509 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002510 check_cursor_col();
2511
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002512 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002513 return FAIL;
2514
2515 if (len_change)
2516 *len_change = 0;
2517
2518 return OK;
2519 }
2520 else
2521 {
2522 PyErr_BadArgument();
2523 return FAIL;
2524 }
2525}
2526
Bram Moolenaar19e60942011-06-19 00:27:51 +02002527/* Replace a range of lines in the specified buffer. The line numbers are in
2528 * Vim format (1-based). The range is from lo up to, but not including, hi.
2529 * The replacement lines are given as a Python list of string objects. The
2530 * list is checked for validity and correct format. Errors are returned as a
2531 * value of FAIL. The return value is OK on success.
2532 * If OK is returned and len_change is not NULL, *len_change
2533 * is set to the change in the buffer length.
2534 */
2535 static int
2536SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2537{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002538 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002539 * There are three cases:
2540 * 1. NULL, or None - this is a deletion.
2541 * 2. A list - this is a replacement.
2542 * 3. Anything else - this is an error.
2543 */
2544 if (list == Py_None || list == NULL)
2545 {
2546 PyInt i;
2547 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002548 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002549
2550 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002551 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002552 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002553
2554 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2555 PyErr_SetVim(_("cannot save undo information"));
2556 else
2557 {
2558 for (i = 0; i < n; ++i)
2559 {
2560 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2561 {
2562 PyErr_SetVim(_("cannot delete line"));
2563 break;
2564 }
2565 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02002566 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002567 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2568 deleted_lines_mark((linenr_T)lo, (long)i);
2569 }
2570
Bram Moolenaar105bc352013-05-17 16:03:57 +02002571 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002572
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002573 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002574 return FAIL;
2575
2576 if (len_change)
2577 *len_change = -n;
2578
2579 return OK;
2580 }
2581 else if (PyList_Check(list))
2582 {
2583 PyInt i;
2584 PyInt new_len = PyList_Size(list);
2585 PyInt old_len = hi - lo;
2586 PyInt extra = 0; /* lines added to text, can be negative */
2587 char **array;
2588 buf_T *savebuf;
2589
2590 if (new_len == 0) /* avoid allocating zero bytes */
2591 array = NULL;
2592 else
2593 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002594 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002595 if (array == NULL)
2596 {
2597 PyErr_NoMemory();
2598 return FAIL;
2599 }
2600 }
2601
2602 for (i = 0; i < new_len; ++i)
2603 {
2604 PyObject *line = PyList_GetItem(list, i);
2605
2606 array[i] = StringToLine(line);
2607 if (array[i] == NULL)
2608 {
2609 while (i)
2610 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002611 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002612 return FAIL;
2613 }
2614 }
2615
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002616 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02002617 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002618
2619 // START of region without "return". Must call restore_buffer()!
2620 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002621
2622 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2623 PyErr_SetVim(_("cannot save undo information"));
2624
2625 /* If the size of the range is reducing (ie, new_len < old_len) we
2626 * need to delete some old_len. We do this at the start, by
2627 * repeatedly deleting line "lo".
2628 */
2629 if (!PyErr_Occurred())
2630 {
2631 for (i = 0; i < old_len - new_len; ++i)
2632 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2633 {
2634 PyErr_SetVim(_("cannot delete line"));
2635 break;
2636 }
2637 extra -= i;
2638 }
2639
2640 /* For as long as possible, replace the existing old_len with the
2641 * new old_len. This is a more efficient operation, as it requires
2642 * less memory allocation and freeing.
2643 */
2644 if (!PyErr_Occurred())
2645 {
2646 for (i = 0; i < old_len && i < new_len; ++i)
2647 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2648 == FAIL)
2649 {
2650 PyErr_SetVim(_("cannot replace line"));
2651 break;
2652 }
2653 }
2654 else
2655 i = 0;
2656
2657 /* Now we may need to insert the remaining new old_len. If we do, we
2658 * must free the strings as we finish with them (we can't pass the
2659 * responsibility to vim in this case).
2660 */
2661 if (!PyErr_Occurred())
2662 {
2663 while (i < new_len)
2664 {
2665 if (ml_append((linenr_T)(lo + i - 1),
2666 (char_u *)array[i], 0, FALSE) == FAIL)
2667 {
2668 PyErr_SetVim(_("cannot insert line"));
2669 break;
2670 }
2671 vim_free(array[i]);
2672 ++i;
2673 ++extra;
2674 }
2675 }
2676
2677 /* Free any left-over old_len, as a result of an error */
2678 while (i < new_len)
2679 {
2680 vim_free(array[i]);
2681 ++i;
2682 }
2683
2684 /* Free the array of old_len. All of its contents have now
2685 * been dealt with (either freed, or the responsibility passed
2686 * to vim.
2687 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002688 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002689
2690 /* Adjust marks. Invalidate any which lie in the
2691 * changed range, and move any in the remainder of the buffer.
2692 */
2693 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2694 (long)MAXLNUM, (long)extra);
2695 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2696
Bram Moolenaar105bc352013-05-17 16:03:57 +02002697 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002698 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2699
Bram Moolenaar105bc352013-05-17 16:03:57 +02002700 // END of region without "return".
2701 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002702
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002703 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002704 return FAIL;
2705
2706 if (len_change)
2707 *len_change = new_len - old_len;
2708
2709 return OK;
2710 }
2711 else
2712 {
2713 PyErr_BadArgument();
2714 return FAIL;
2715 }
2716}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002717
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002718/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002719 * The line number is in Vim format (1-based). The lines to be inserted are
2720 * given as a Python list of string objects or as a single string. The lines
2721 * to be added are checked for validity and correct format. Errors are
2722 * returned as a value of FAIL. The return value is OK on success.
2723 * If OK is returned and len_change is not NULL, *len_change
2724 * is set to the change in the buffer length.
2725 */
2726 static int
2727InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2728{
2729 /* First of all, we check the type of the supplied Python object.
2730 * It must be a string or a list, or the call is in error.
2731 */
2732 if (PyString_Check(lines))
2733 {
2734 char *str = StringToLine(lines);
2735 buf_T *savebuf;
2736
2737 if (str == NULL)
2738 return FAIL;
2739
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002740 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002741 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002742 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002743
2744 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2745 PyErr_SetVim(_("cannot save undo information"));
2746 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2747 PyErr_SetVim(_("cannot insert line"));
2748 else
2749 appended_lines_mark((linenr_T)n, 1L);
2750
2751 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002752 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002753 update_screen(VALID);
2754
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002755 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002756 return FAIL;
2757
2758 if (len_change)
2759 *len_change = 1;
2760
2761 return OK;
2762 }
2763 else if (PyList_Check(lines))
2764 {
2765 PyInt i;
2766 PyInt size = PyList_Size(lines);
2767 char **array;
2768 buf_T *savebuf;
2769
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002770 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002771 if (array == NULL)
2772 {
2773 PyErr_NoMemory();
2774 return FAIL;
2775 }
2776
2777 for (i = 0; i < size; ++i)
2778 {
2779 PyObject *line = PyList_GetItem(lines, i);
2780 array[i] = StringToLine(line);
2781
2782 if (array[i] == NULL)
2783 {
2784 while (i)
2785 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002786 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002787 return FAIL;
2788 }
2789 }
2790
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002791 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002792 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002793 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002794
2795 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2796 PyErr_SetVim(_("cannot save undo information"));
2797 else
2798 {
2799 for (i = 0; i < size; ++i)
2800 {
2801 if (ml_append((linenr_T)(n + i),
2802 (char_u *)array[i], 0, FALSE) == FAIL)
2803 {
2804 PyErr_SetVim(_("cannot insert line"));
2805
2806 /* Free the rest of the lines */
2807 while (i < size)
2808 vim_free(array[i++]);
2809
2810 break;
2811 }
2812 vim_free(array[i]);
2813 }
2814 if (i > 0)
2815 appended_lines_mark((linenr_T)n, (long)i);
2816 }
2817
2818 /* Free the array of lines. All of its contents have now
2819 * been freed.
2820 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002821 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002822
Bram Moolenaar105bc352013-05-17 16:03:57 +02002823 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002824 update_screen(VALID);
2825
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002826 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002827 return FAIL;
2828
2829 if (len_change)
2830 *len_change = size;
2831
2832 return OK;
2833 }
2834 else
2835 {
2836 PyErr_BadArgument();
2837 return FAIL;
2838 }
2839}
2840
2841/*
2842 * Common routines for buffers and line ranges
2843 * -------------------------------------------
2844 */
2845
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002846typedef struct
2847{
2848 PyObject_HEAD
2849 buf_T *buf;
2850} BufferObject;
2851
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002852 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002853CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002854{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002855 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002856 {
2857 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2858 return -1;
2859 }
2860
2861 return 0;
2862}
2863
2864 static PyObject *
2865RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2866{
2867 if (CheckBuffer(self))
2868 return NULL;
2869
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002870 if (end == -1)
2871 end = self->buf->b_ml.ml_line_count;
2872
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002873 if (n < 0)
2874 n += end - start + 1;
2875
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002876 if (n < 0 || n > end - start)
2877 {
2878 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2879 return NULL;
2880 }
2881
2882 return GetBufferLine(self->buf, n+start);
2883}
2884
2885 static PyObject *
2886RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2887{
2888 PyInt size;
2889
2890 if (CheckBuffer(self))
2891 return NULL;
2892
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002893 if (end == -1)
2894 end = self->buf->b_ml.ml_line_count;
2895
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002896 size = end - start + 1;
2897
2898 if (lo < 0)
2899 lo = 0;
2900 else if (lo > size)
2901 lo = size;
2902 if (hi < 0)
2903 hi = 0;
2904 if (hi < lo)
2905 hi = lo;
2906 else if (hi > size)
2907 hi = size;
2908
2909 return GetBufferLineList(self->buf, lo+start, hi+start);
2910}
2911
2912 static PyInt
2913RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2914{
2915 PyInt len_change;
2916
2917 if (CheckBuffer(self))
2918 return -1;
2919
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002920 if (end == -1)
2921 end = self->buf->b_ml.ml_line_count;
2922
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002923 if (n < 0)
2924 n += end - start + 1;
2925
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002926 if (n < 0 || n > end - start)
2927 {
2928 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2929 return -1;
2930 }
2931
2932 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2933 return -1;
2934
2935 if (new_end)
2936 *new_end = end + len_change;
2937
2938 return 0;
2939}
2940
Bram Moolenaar19e60942011-06-19 00:27:51 +02002941 static PyInt
2942RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2943{
2944 PyInt size;
2945 PyInt len_change;
2946
2947 /* Self must be a valid buffer */
2948 if (CheckBuffer(self))
2949 return -1;
2950
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002951 if (end == -1)
2952 end = self->buf->b_ml.ml_line_count;
2953
Bram Moolenaar19e60942011-06-19 00:27:51 +02002954 /* Sort out the slice range */
2955 size = end - start + 1;
2956
2957 if (lo < 0)
2958 lo = 0;
2959 else if (lo > size)
2960 lo = size;
2961 if (hi < 0)
2962 hi = 0;
2963 if (hi < lo)
2964 hi = lo;
2965 else if (hi > size)
2966 hi = size;
2967
2968 if (SetBufferLineList(self->buf, lo + start, hi + start,
2969 val, &len_change) == FAIL)
2970 return -1;
2971
2972 if (new_end)
2973 *new_end = end + len_change;
2974
2975 return 0;
2976}
2977
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002978
2979 static PyObject *
2980RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2981{
2982 PyObject *lines;
2983 PyInt len_change;
2984 PyInt max;
2985 PyInt n;
2986
2987 if (CheckBuffer(self))
2988 return NULL;
2989
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002990 if (end == -1)
2991 end = self->buf->b_ml.ml_line_count;
2992
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002993 max = n = end - start + 1;
2994
2995 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2996 return NULL;
2997
2998 if (n < 0 || n > max)
2999 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003000 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003001 return NULL;
3002 }
3003
3004 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
3005 return NULL;
3006
3007 if (new_end)
3008 *new_end = end + len_change;
3009
3010 Py_INCREF(Py_None);
3011 return Py_None;
3012}
3013
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003014/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003015 */
3016
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003017static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003018static PySequenceMethods RangeAsSeq;
3019static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003020
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003021typedef struct
3022{
3023 PyObject_HEAD
3024 BufferObject *buf;
3025 PyInt start;
3026 PyInt end;
3027} RangeObject;
3028
3029 static PyObject *
3030RangeNew(buf_T *buf, PyInt start, PyInt end)
3031{
3032 BufferObject *bufr;
3033 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003034 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003035 if (self == NULL)
3036 return NULL;
3037
3038 bufr = (BufferObject *)BufferNew(buf);
3039 if (bufr == NULL)
3040 {
3041 Py_DECREF(self);
3042 return NULL;
3043 }
3044 Py_INCREF(bufr);
3045
3046 self->buf = bufr;
3047 self->start = start;
3048 self->end = end;
3049
3050 return (PyObject *)(self);
3051}
3052
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003053 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003054RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003055{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003056 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003057 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02003058 PyObject_GC_Del((void *)(self));
3059}
3060
3061 static int
3062RangeTraverse(RangeObject *self, visitproc visit, void *arg)
3063{
3064 Py_VISIT(((PyObject *)(self->buf)));
3065 return 0;
3066}
3067
3068 static int
3069RangeClear(RangeObject *self)
3070{
3071 Py_CLEAR(self->buf);
3072 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003073}
3074
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003075 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003076RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003077{
3078 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003079 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003080 return -1; /* ??? */
3081
Bram Moolenaard6e39182013-05-21 18:30:34 +02003082 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003083}
3084
3085 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003086RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003087{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003088 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003089}
3090
3091 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003092RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003093{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003094 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003095}
3096
3097 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003098RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003099{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003100 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003101}
3102
3103 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003104RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003105{
3106 static char repr[100];
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003107
Bram Moolenaard6e39182013-05-21 18:30:34 +02003108 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003109 {
3110 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
3111 (self));
3112 return PyString_FromString(repr);
3113 }
3114 else
3115 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003116 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003117 int len;
3118
3119 if (name == NULL)
3120 name = "";
3121 len = (int)strlen(name);
3122
3123 if (len > 45)
3124 name = name + (45 - len);
3125
3126 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
3127 len > 45 ? "..." : "", name,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003128 self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003129
3130 return PyString_FromString(repr);
3131 }
3132}
3133
3134static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003135 /* name, function, calling, documentation */
3136 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
3137 { NULL, NULL, 0, NULL }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003138};
3139
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003140static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003141static PySequenceMethods BufferAsSeq;
3142static PyMappingMethods BufferAsMapping;
3143
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003144 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02003145BufferNew(buf_T *buf)
3146{
3147 /* We need to handle deletion of buffers underneath us.
3148 * If we add a "b_python*_ref" field to the buf_T structure,
3149 * then we can get at it in buf_freeall() in vim. We then
3150 * need to create only ONE Python object per buffer - if
3151 * we try to create a second, just INCREF the existing one
3152 * and return it. The (single) Python object referring to
3153 * the buffer is stored in "b_python*_ref".
3154 * Question: what to do on a buf_freeall(). We'll probably
3155 * have to either delete the Python object (DECREF it to
3156 * zero - a bad idea, as it leaves dangling refs!) or
3157 * set the buf_T * value to an invalid value (-1?), which
3158 * means we need checks in all access functions... Bah.
3159 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003160 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003161 * b_python_ref and b_python3_ref fields respectively.
3162 */
3163
3164 BufferObject *self;
3165
3166 if (BUF_PYTHON_REF(buf) != NULL)
3167 {
3168 self = BUF_PYTHON_REF(buf);
3169 Py_INCREF(self);
3170 }
3171 else
3172 {
3173 self = PyObject_NEW(BufferObject, &BufferType);
3174 if (self == NULL)
3175 return NULL;
3176 self->buf = buf;
3177 BUF_PYTHON_REF(buf) = self;
3178 }
3179
3180 return (PyObject *)(self);
3181}
3182
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003183 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003184BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003185{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003186 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3187 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003188
3189 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003190}
3191
Bram Moolenaar971db462013-05-12 18:44:48 +02003192 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003193BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003194{
3195 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003196 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003197 return -1; /* ??? */
3198
Bram Moolenaard6e39182013-05-21 18:30:34 +02003199 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003200}
3201
3202 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003203BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003204{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003205 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003206}
3207
3208 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003209BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003210{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003211 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003212}
3213
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003214 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003215BufferAttrValid(BufferObject *self, char *name)
3216{
3217 PyObject *r;
3218
3219 if (strcmp(name, "valid") != 0)
3220 return NULL;
3221
3222 r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
3223 Py_INCREF(r);
3224 return r;
3225}
3226
3227 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003228BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003229{
3230 if (strcmp(name, "name") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003231 return Py_BuildValue("s", self->buf->b_ffname);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003232 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003233 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003234 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003235 return DictionaryNew(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003236 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003237 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3238 (PyObject *) self);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003239 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003240 return Py_BuildValue("[sssss]", "name", "number", "vars", "options",
3241 "valid");
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003242 else
3243 return NULL;
3244}
3245
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003246 static int
3247BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
3248{
3249 if (CheckBuffer(self))
3250 return -1;
3251
3252 if (strcmp(name, "name") == 0)
3253 {
3254 char_u *val;
3255 aco_save_T aco;
3256 int r;
3257 PyObject *todecref;
3258
3259 if (!(val = StringToChars(valObject, &todecref)))
3260 return -1;
3261
3262 VimTryStart();
3263 /* Using aucmd_*: autocommands will be executed by rename_buffer */
3264 aucmd_prepbuf(&aco, self->buf);
3265 r = rename_buffer(val);
3266 aucmd_restbuf(&aco);
3267 Py_XDECREF(todecref);
3268 if (VimTryEnd())
3269 return -1;
3270
3271 if (r == FAIL)
3272 {
3273 PyErr_SetVim(_("failed to rename buffer"));
3274 return -1;
3275 }
3276 return 0;
3277 }
3278 else
3279 {
3280 PyErr_SetString(PyExc_AttributeError, name);
3281 return -1;
3282 }
3283}
3284
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003285 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003286BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003287{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003288 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003289}
3290
3291 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003292BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003293{
3294 pos_T *posp;
3295 char *pmark;
3296 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02003297 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003298
Bram Moolenaard6e39182013-05-21 18:30:34 +02003299 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003300 return NULL;
3301
3302 if (!PyArg_ParseTuple(args, "s", &pmark))
3303 return NULL;
3304 mark = *pmark;
3305
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003306 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02003307 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003308 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003309 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003310 if (VimTryEnd())
3311 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003312
3313 if (posp == NULL)
3314 {
3315 PyErr_SetVim(_("invalid mark name"));
3316 return NULL;
3317 }
3318
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003319 if (posp->lnum <= 0)
3320 {
3321 /* Or raise an error? */
3322 Py_INCREF(Py_None);
3323 return Py_None;
3324 }
3325
3326 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3327}
3328
3329 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003330BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003331{
3332 PyInt start;
3333 PyInt end;
3334
Bram Moolenaard6e39182013-05-21 18:30:34 +02003335 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003336 return NULL;
3337
3338 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3339 return NULL;
3340
Bram Moolenaard6e39182013-05-21 18:30:34 +02003341 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003342}
3343
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003344 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003345BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003346{
3347 static char repr[100];
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003348
Bram Moolenaard6e39182013-05-21 18:30:34 +02003349 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003350 {
3351 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3352 return PyString_FromString(repr);
3353 }
3354 else
3355 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003356 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003357 PyInt len;
3358
3359 if (name == NULL)
3360 name = "";
3361 len = strlen(name);
3362
3363 if (len > 35)
3364 name = name + (35 - len);
3365
3366 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3367
3368 return PyString_FromString(repr);
3369 }
3370}
3371
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003372static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003373 /* name, function, calling, documentation */
3374 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
3375 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
3376 {"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 +01003377#if PY_VERSION_HEX >= 0x03000000
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003378 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, "List buffer attributes" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01003379#endif
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003380 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003381};
3382
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003383/*
3384 * Buffer list object - Implementation
3385 */
3386
3387static PyTypeObject BufMapType;
3388
3389typedef struct
3390{
3391 PyObject_HEAD
3392} BufMapObject;
3393
3394 static PyInt
3395BufMapLength(PyObject *self UNUSED)
3396{
3397 buf_T *b = firstbuf;
3398 PyInt n = 0;
3399
3400 while (b)
3401 {
3402 ++n;
3403 b = b->b_next;
3404 }
3405
3406 return n;
3407}
3408
3409 static PyObject *
3410BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3411{
3412 buf_T *b;
3413 int bnr;
3414
3415#if PY_MAJOR_VERSION < 3
3416 if (PyInt_Check(keyObject))
3417 bnr = PyInt_AsLong(keyObject);
3418 else
3419#endif
3420 if (PyLong_Check(keyObject))
3421 bnr = PyLong_AsLong(keyObject);
3422 else
3423 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003424 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003425 return NULL;
3426 }
3427
3428 b = buflist_findnr(bnr);
3429
3430 if (b)
3431 return BufferNew(b);
3432 else
3433 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003434 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003435 return NULL;
3436 }
3437}
3438
3439 static void
3440BufMapIterDestruct(PyObject *buffer)
3441{
3442 /* Iteration was stopped before all buffers were processed */
3443 if (buffer)
3444 {
3445 Py_DECREF(buffer);
3446 }
3447}
3448
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003449 static int
3450BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
3451{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003452 if (buffer)
3453 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003454 return 0;
3455}
3456
3457 static int
3458BufMapIterClear(PyObject **buffer)
3459{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003460 if (*buffer)
3461 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003462 return 0;
3463}
3464
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003465 static PyObject *
3466BufMapIterNext(PyObject **buffer)
3467{
3468 PyObject *next;
3469 PyObject *r;
3470
3471 if (!*buffer)
3472 return NULL;
3473
3474 r = *buffer;
3475
3476 if (CheckBuffer((BufferObject *)(r)))
3477 {
3478 *buffer = NULL;
3479 return NULL;
3480 }
3481
3482 if (!((BufferObject *)(r))->buf->b_next)
3483 next = NULL;
3484 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3485 return NULL;
3486 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02003487 /* Do not increment reference: we no longer hold it (decref), but whoever
3488 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003489 return r;
3490}
3491
3492 static PyObject *
3493BufMapIter(PyObject *self UNUSED)
3494{
3495 PyObject *buffer;
3496
3497 buffer = BufferNew(firstbuf);
3498 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003499 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
3500 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003501}
3502
3503static PyMappingMethods BufMapAsMapping = {
3504 (lenfunc) BufMapLength,
3505 (binaryfunc) BufMapItem,
3506 (objobjargproc) 0,
3507};
3508
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003509/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003510 */
3511
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003512 static PyObject *
3513CurrentGetattr(PyObject *self UNUSED, char *name)
3514{
3515 if (strcmp(name, "buffer") == 0)
3516 return (PyObject *)BufferNew(curbuf);
3517 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003518 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003519 else if (strcmp(name, "tabpage") == 0)
3520 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003521 else if (strcmp(name, "line") == 0)
3522 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3523 else if (strcmp(name, "range") == 0)
3524 return RangeNew(curbuf, RangeStart, RangeEnd);
3525 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003526 return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
3527 "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003528 else
3529 {
3530 PyErr_SetString(PyExc_AttributeError, name);
3531 return NULL;
3532 }
3533}
3534
3535 static int
3536CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3537{
3538 if (strcmp(name, "line") == 0)
3539 {
3540 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3541 return -1;
3542
3543 return 0;
3544 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003545 else if (strcmp(name, "buffer") == 0)
3546 {
3547 int count;
3548
3549 if (value->ob_type != &BufferType)
3550 {
3551 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3552 return -1;
3553 }
3554
3555 if (CheckBuffer((BufferObject *)(value)))
3556 return -1;
3557 count = ((BufferObject *)(value))->buf->b_fnum;
3558
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003559 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003560 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3561 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003562 if (VimTryEnd())
3563 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003564 PyErr_SetVim(_("failed to switch to given buffer"));
3565 return -1;
3566 }
3567
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003568 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003569 }
3570 else if (strcmp(name, "window") == 0)
3571 {
3572 int count;
3573
3574 if (value->ob_type != &WindowType)
3575 {
3576 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3577 return -1;
3578 }
3579
3580 if (CheckWindow((WindowObject *)(value)))
3581 return -1;
3582 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3583
3584 if (!count)
3585 {
3586 PyErr_SetString(PyExc_ValueError,
3587 _("failed to find window in the current tab page"));
3588 return -1;
3589 }
3590
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003591 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003592 win_goto(((WindowObject *)(value))->win);
3593 if (((WindowObject *)(value))->win != curwin)
3594 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003595 if (VimTryEnd())
3596 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003597 PyErr_SetString(PyExc_RuntimeError,
3598 _("did not switch to the specified window"));
3599 return -1;
3600 }
3601
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003602 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003603 }
3604 else if (strcmp(name, "tabpage") == 0)
3605 {
3606 if (value->ob_type != &TabPageType)
3607 {
3608 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3609 return -1;
3610 }
3611
3612 if (CheckTabPage((TabPageObject *)(value)))
3613 return -1;
3614
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003615 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003616 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3617 if (((TabPageObject *)(value))->tab != curtab)
3618 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003619 if (VimTryEnd())
3620 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003621 PyErr_SetString(PyExc_RuntimeError,
3622 _("did not switch to the specified tab page"));
3623 return -1;
3624 }
3625
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003626 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003627 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003628 else
3629 {
3630 PyErr_SetString(PyExc_AttributeError, name);
3631 return -1;
3632 }
3633}
3634
Bram Moolenaardb913952012-06-29 12:54:53 +02003635 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003636init_range_cmd(exarg_T *eap)
3637{
3638 RangeStart = eap->line1;
3639 RangeEnd = eap->line2;
3640}
3641
3642 static void
3643init_range_eval(typval_T *rettv UNUSED)
3644{
3645 RangeStart = (PyInt) curwin->w_cursor.lnum;
3646 RangeEnd = RangeStart;
3647}
3648
3649 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003650run_cmd(const char *cmd, void *arg UNUSED
3651#ifdef PY_CAN_RECURSE
3652 , PyGILState_STATE *pygilstate UNUSED
3653#endif
3654 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003655{
3656 PyRun_SimpleString((char *) cmd);
3657}
3658
3659static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
3660static int code_hdr_len = 30;
3661
3662 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003663run_do(const char *cmd, void *arg UNUSED
3664#ifdef PY_CAN_RECURSE
3665 , PyGILState_STATE *pygilstate
3666#endif
3667 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003668{
3669 PyInt lnum;
3670 size_t len;
3671 char *code;
3672 int status;
3673 PyObject *pyfunc, *pymain;
3674
Bram Moolenaar4ac66762013-05-28 22:31:46 +02003675 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003676 {
3677 EMSG(_("cannot save undo information"));
3678 return;
3679 }
3680
3681 len = code_hdr_len + STRLEN(cmd);
3682 code = PyMem_New(char, len + 1);
3683 memcpy(code, code_hdr, code_hdr_len);
3684 STRCPY(code + code_hdr_len, cmd);
3685 status = PyRun_SimpleString(code);
3686 PyMem_Free(code);
3687
3688 if (status)
3689 {
3690 EMSG(_("failed to run the code"));
3691 return;
3692 }
3693
3694 status = 0;
3695 pymain = PyImport_AddModule("__main__");
3696 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003697#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003698 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003699#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003700
3701 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
3702 {
3703 PyObject *line, *linenr, *ret;
3704
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003705#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003706 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003707#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003708 if (!(line = GetBufferLine(curbuf, lnum)))
3709 goto err;
3710 if (!(linenr = PyInt_FromLong((long) lnum)))
3711 {
3712 Py_DECREF(line);
3713 goto err;
3714 }
3715 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
3716 Py_DECREF(line);
3717 Py_DECREF(linenr);
3718 if (!ret)
3719 goto err;
3720
3721 if (ret != Py_None)
3722 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
3723 goto err;
3724
3725 Py_XDECREF(ret);
3726 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003727#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003728 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003729#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003730 }
3731 goto out;
3732err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003733#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003734 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003735#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003736 PyErr_PrintEx(0);
3737 PythonIO_Flush();
3738 status = 1;
3739out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003740#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003741 if (!status)
3742 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003743#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003744 Py_DECREF(pyfunc);
3745 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
3746 if (status)
3747 return;
3748 check_cursor();
3749 update_curbuf(NOT_VALID);
3750}
3751
3752 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003753run_eval(const char *cmd, typval_T *rettv
3754#ifdef PY_CAN_RECURSE
3755 , PyGILState_STATE *pygilstate UNUSED
3756#endif
3757 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003758{
3759 PyObject *r;
3760
3761 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
3762 if (r == NULL)
3763 {
3764 if (PyErr_Occurred() && !msg_silent)
3765 PyErr_PrintEx(0);
3766 EMSG(_("E858: Eval did not return a valid python object"));
3767 }
3768 else
3769 {
3770 if (ConvertFromPyObject(r, rettv) == -1)
3771 EMSG(_("E859: Failed to convert returned python object to vim value"));
3772 Py_DECREF(r);
3773 }
3774 PyErr_Clear();
3775}
3776
3777 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02003778set_ref_in_py(const int copyID)
3779{
3780 pylinkedlist_T *cur;
3781 dict_T *dd;
3782 list_T *ll;
3783
3784 if (lastdict != NULL)
3785 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3786 {
3787 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3788 if (dd->dv_copyID != copyID)
3789 {
3790 dd->dv_copyID = copyID;
3791 set_ref_in_ht(&dd->dv_hashtab, copyID);
3792 }
3793 }
3794
3795 if (lastlist != NULL)
3796 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3797 {
3798 ll = ((ListObject *) (cur->pll_obj))->list;
3799 if (ll->lv_copyID != copyID)
3800 {
3801 ll->lv_copyID = copyID;
3802 set_ref_in_list(ll, copyID);
3803 }
3804 }
3805}
3806
3807 static int
3808set_string_copy(char_u *str, typval_T *tv)
3809{
3810 tv->vval.v_string = vim_strsave(str);
3811 if (tv->vval.v_string == NULL)
3812 {
3813 PyErr_NoMemory();
3814 return -1;
3815 }
3816 return 0;
3817}
3818
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003819 static int
3820pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3821{
3822 dict_T *d;
3823 char_u *key;
3824 dictitem_T *di;
3825 PyObject *keyObject;
3826 PyObject *valObject;
3827 Py_ssize_t iter = 0;
3828
3829 d = dict_alloc();
3830 if (d == NULL)
3831 {
3832 PyErr_NoMemory();
3833 return -1;
3834 }
3835
3836 tv->v_type = VAR_DICT;
3837 tv->vval.v_dict = d;
3838
3839 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
3840 {
3841 DICTKEY_DECL
3842
3843 if (keyObject == NULL)
3844 return -1;
3845 if (valObject == NULL)
3846 return -1;
3847
3848 DICTKEY_GET_NOTEMPTY(-1)
3849
3850 di = dictitem_alloc(key);
3851
3852 DICTKEY_UNREF
3853
3854 if (di == NULL)
3855 {
3856 PyErr_NoMemory();
3857 return -1;
3858 }
3859 di->di_tv.v_lock = 0;
3860
3861 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3862 {
3863 vim_free(di);
3864 return -1;
3865 }
3866 if (dict_add(d, di) == FAIL)
3867 {
3868 vim_free(di);
3869 PyErr_SetVim(_("failed to add key to dictionary"));
3870 return -1;
3871 }
3872 }
3873 return 0;
3874}
3875
3876 static int
3877pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3878{
3879 dict_T *d;
3880 char_u *key;
3881 dictitem_T *di;
3882 PyObject *list;
3883 PyObject *litem;
3884 PyObject *keyObject;
3885 PyObject *valObject;
3886 Py_ssize_t lsize;
3887
3888 d = dict_alloc();
3889 if (d == NULL)
3890 {
3891 PyErr_NoMemory();
3892 return -1;
3893 }
3894
3895 tv->v_type = VAR_DICT;
3896 tv->vval.v_dict = d;
3897
3898 list = PyMapping_Items(obj);
3899 if (list == NULL)
3900 return -1;
3901 lsize = PyList_Size(list);
3902 while (lsize--)
3903 {
3904 DICTKEY_DECL
3905
3906 litem = PyList_GetItem(list, lsize);
3907 if (litem == NULL)
3908 {
3909 Py_DECREF(list);
3910 return -1;
3911 }
3912
3913 keyObject = PyTuple_GetItem(litem, 0);
3914 if (keyObject == NULL)
3915 {
3916 Py_DECREF(list);
3917 Py_DECREF(litem);
3918 return -1;
3919 }
3920
3921 DICTKEY_GET_NOTEMPTY(-1)
3922
3923 valObject = PyTuple_GetItem(litem, 1);
3924 if (valObject == NULL)
3925 {
3926 Py_DECREF(list);
3927 Py_DECREF(litem);
3928 return -1;
3929 }
3930
3931 di = dictitem_alloc(key);
3932
3933 DICTKEY_UNREF
3934
3935 if (di == NULL)
3936 {
3937 Py_DECREF(list);
3938 Py_DECREF(litem);
3939 PyErr_NoMemory();
3940 return -1;
3941 }
3942 di->di_tv.v_lock = 0;
3943
3944 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3945 {
3946 vim_free(di);
3947 Py_DECREF(list);
3948 Py_DECREF(litem);
3949 return -1;
3950 }
3951 if (dict_add(d, di) == FAIL)
3952 {
3953 vim_free(di);
3954 Py_DECREF(list);
3955 Py_DECREF(litem);
3956 PyErr_SetVim(_("failed to add key to dictionary"));
3957 return -1;
3958 }
3959 Py_DECREF(litem);
3960 }
3961 Py_DECREF(list);
3962 return 0;
3963}
3964
3965 static int
3966pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3967{
3968 list_T *l;
3969
3970 l = list_alloc();
3971 if (l == NULL)
3972 {
3973 PyErr_NoMemory();
3974 return -1;
3975 }
3976
3977 tv->v_type = VAR_LIST;
3978 tv->vval.v_list = l;
3979
3980 if (list_py_concat(l, obj, lookupDict) == -1)
3981 return -1;
3982
3983 return 0;
3984}
3985
3986 static int
3987pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3988{
3989 PyObject *iterator = PyObject_GetIter(obj);
3990 PyObject *item;
3991 list_T *l;
3992 listitem_T *li;
3993
3994 l = list_alloc();
3995
3996 if (l == NULL)
3997 {
3998 PyErr_NoMemory();
3999 return -1;
4000 }
4001
4002 tv->vval.v_list = l;
4003 tv->v_type = VAR_LIST;
4004
4005
4006 if (iterator == NULL)
4007 return -1;
4008
4009 while ((item = PyIter_Next(obj)))
4010 {
4011 li = listitem_alloc();
4012 if (li == NULL)
4013 {
4014 PyErr_NoMemory();
4015 return -1;
4016 }
4017 li->li_tv.v_lock = 0;
4018
4019 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
4020 return -1;
4021
4022 list_append(l, li);
4023
4024 Py_DECREF(item);
4025 }
4026
4027 Py_DECREF(iterator);
4028 return 0;
4029}
4030
Bram Moolenaardb913952012-06-29 12:54:53 +02004031typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
4032
4033 static int
4034convert_dl(PyObject *obj, typval_T *tv,
4035 pytotvfunc py_to_tv, PyObject *lookupDict)
4036{
4037 PyObject *capsule;
4038 char hexBuf[sizeof(void *) * 2 + 3];
4039
4040 sprintf(hexBuf, "%p", obj);
4041
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004042# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004043 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004044# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004045 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004046# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02004047 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02004048 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004049# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004050 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02004051# else
4052 capsule = PyCObject_FromVoidPtr(tv, NULL);
4053# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004054 PyDict_SetItemString(lookupDict, hexBuf, capsule);
4055 Py_DECREF(capsule);
4056 if (py_to_tv(obj, tv, lookupDict) == -1)
4057 {
4058 tv->v_type = VAR_UNKNOWN;
4059 return -1;
4060 }
4061 /* As we are not using copy_tv which increments reference count we must
4062 * do it ourself. */
4063 switch(tv->v_type)
4064 {
4065 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
4066 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
4067 }
4068 }
4069 else
4070 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004071 typval_T *v;
4072
4073# ifdef PY_USE_CAPSULE
4074 v = PyCapsule_GetPointer(capsule, NULL);
4075# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004076 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004077# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004078 copy_tv(v, tv);
4079 }
4080 return 0;
4081}
4082
4083 static int
4084ConvertFromPyObject(PyObject *obj, typval_T *tv)
4085{
4086 PyObject *lookup_dict;
4087 int r;
4088
4089 lookup_dict = PyDict_New();
4090 r = _ConvertFromPyObject(obj, tv, lookup_dict);
4091 Py_DECREF(lookup_dict);
4092 return r;
4093}
4094
4095 static int
4096_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
4097{
4098 if (obj->ob_type == &DictionaryType)
4099 {
4100 tv->v_type = VAR_DICT;
4101 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4102 ++tv->vval.v_dict->dv_refcount;
4103 }
4104 else if (obj->ob_type == &ListType)
4105 {
4106 tv->v_type = VAR_LIST;
4107 tv->vval.v_list = (((ListObject *)(obj))->list);
4108 ++tv->vval.v_list->lv_refcount;
4109 }
4110 else if (obj->ob_type == &FunctionType)
4111 {
4112 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
4113 return -1;
4114
4115 tv->v_type = VAR_FUNC;
4116 func_ref(tv->vval.v_string);
4117 }
Bram Moolenaardb913952012-06-29 12:54:53 +02004118 else if (PyBytes_Check(obj))
4119 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004120 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02004121
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004122 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
4123 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004124 if (result == NULL)
4125 return -1;
4126
4127 if (set_string_copy(result, tv) == -1)
4128 return -1;
4129
4130 tv->v_type = VAR_STRING;
4131 }
4132 else if (PyUnicode_Check(obj))
4133 {
4134 PyObject *bytes;
4135 char_u *result;
4136
Bram Moolenaardb913952012-06-29 12:54:53 +02004137 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
4138 if (bytes == NULL)
4139 return -1;
4140
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004141 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
4142 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004143 if (result == NULL)
4144 return -1;
4145
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004146 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02004147 {
4148 Py_XDECREF(bytes);
4149 return -1;
4150 }
4151 Py_XDECREF(bytes);
4152
4153 tv->v_type = VAR_STRING;
4154 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02004155#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02004156 else if (PyInt_Check(obj))
4157 {
4158 tv->v_type = VAR_NUMBER;
4159 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
4160 }
4161#endif
4162 else if (PyLong_Check(obj))
4163 {
4164 tv->v_type = VAR_NUMBER;
4165 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
4166 }
4167 else if (PyDict_Check(obj))
4168 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
4169#ifdef FEAT_FLOAT
4170 else if (PyFloat_Check(obj))
4171 {
4172 tv->v_type = VAR_FLOAT;
4173 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
4174 }
4175#endif
4176 else if (PyIter_Check(obj))
4177 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
4178 else if (PySequence_Check(obj))
4179 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
4180 else if (PyMapping_Check(obj))
4181 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
4182 else
4183 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004184 PyErr_SetString(PyExc_TypeError,
4185 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02004186 return -1;
4187 }
4188 return 0;
4189}
4190
4191 static PyObject *
4192ConvertToPyObject(typval_T *tv)
4193{
4194 if (tv == NULL)
4195 {
4196 PyErr_SetVim(_("NULL reference passed"));
4197 return NULL;
4198 }
4199 switch (tv->v_type)
4200 {
4201 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004202 return PyBytes_FromString(tv->vval.v_string == NULL
4203 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004204 case VAR_NUMBER:
4205 return PyLong_FromLong((long) tv->vval.v_number);
4206#ifdef FEAT_FLOAT
4207 case VAR_FLOAT:
4208 return PyFloat_FromDouble((double) tv->vval.v_float);
4209#endif
4210 case VAR_LIST:
4211 return ListNew(tv->vval.v_list);
4212 case VAR_DICT:
4213 return DictionaryNew(tv->vval.v_dict);
4214 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004215 return FunctionNew(tv->vval.v_string == NULL
4216 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004217 case VAR_UNKNOWN:
4218 Py_INCREF(Py_None);
4219 return Py_None;
4220 default:
4221 PyErr_SetVim(_("internal error: invalid value type"));
4222 return NULL;
4223 }
4224}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004225
4226typedef struct
4227{
4228 PyObject_HEAD
4229} CurrentObject;
4230static PyTypeObject CurrentType;
4231
4232 static void
4233init_structs(void)
4234{
4235 vim_memset(&OutputType, 0, sizeof(OutputType));
4236 OutputType.tp_name = "vim.message";
4237 OutputType.tp_basicsize = sizeof(OutputObject);
4238 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
4239 OutputType.tp_doc = "vim message object";
4240 OutputType.tp_methods = OutputMethods;
4241#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004242 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
4243 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004244 OutputType.tp_alloc = call_PyType_GenericAlloc;
4245 OutputType.tp_new = call_PyType_GenericNew;
4246 OutputType.tp_free = call_PyObject_Free;
4247#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004248 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
4249 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004250#endif
4251
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004252 vim_memset(&IterType, 0, sizeof(IterType));
4253 IterType.tp_name = "vim.iter";
4254 IterType.tp_basicsize = sizeof(IterObject);
4255 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
4256 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004257 IterType.tp_iter = (getiterfunc)IterIter;
4258 IterType.tp_iternext = (iternextfunc)IterNext;
4259 IterType.tp_dealloc = (destructor)IterDestructor;
4260 IterType.tp_traverse = (traverseproc)IterTraverse;
4261 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004262
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004263 vim_memset(&BufferType, 0, sizeof(BufferType));
4264 BufferType.tp_name = "vim.buffer";
4265 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004266 BufferType.tp_dealloc = (destructor)BufferDestructor;
4267 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004268 BufferType.tp_as_sequence = &BufferAsSeq;
4269 BufferType.tp_as_mapping = &BufferAsMapping;
4270 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
4271 BufferType.tp_doc = "vim buffer object";
4272 BufferType.tp_methods = BufferMethods;
4273#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004274 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004275 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004276 BufferType.tp_alloc = call_PyType_GenericAlloc;
4277 BufferType.tp_new = call_PyType_GenericNew;
4278 BufferType.tp_free = call_PyObject_Free;
4279#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004280 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004281 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004282#endif
4283
4284 vim_memset(&WindowType, 0, sizeof(WindowType));
4285 WindowType.tp_name = "vim.window";
4286 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004287 WindowType.tp_dealloc = (destructor)WindowDestructor;
4288 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004289 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
4290 WindowType.tp_doc = "vim Window object";
4291 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004292 WindowType.tp_traverse = (traverseproc)WindowTraverse;
4293 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004294#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004295 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
4296 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004297 WindowType.tp_alloc = call_PyType_GenericAlloc;
4298 WindowType.tp_new = call_PyType_GenericNew;
4299 WindowType.tp_free = call_PyObject_Free;
4300#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004301 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
4302 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004303#endif
4304
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004305 vim_memset(&TabPageType, 0, sizeof(TabPageType));
4306 TabPageType.tp_name = "vim.tabpage";
4307 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004308 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
4309 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004310 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
4311 TabPageType.tp_doc = "vim tab page object";
4312 TabPageType.tp_methods = TabPageMethods;
4313#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004314 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004315 TabPageType.tp_alloc = call_PyType_GenericAlloc;
4316 TabPageType.tp_new = call_PyType_GenericNew;
4317 TabPageType.tp_free = call_PyObject_Free;
4318#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004319 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004320#endif
4321
Bram Moolenaardfa38d42013-05-15 13:38:47 +02004322 vim_memset(&BufMapType, 0, sizeof(BufMapType));
4323 BufMapType.tp_name = "vim.bufferlist";
4324 BufMapType.tp_basicsize = sizeof(BufMapObject);
4325 BufMapType.tp_as_mapping = &BufMapAsMapping;
4326 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004327 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004328 BufferType.tp_doc = "vim buffer list";
4329
4330 vim_memset(&WinListType, 0, sizeof(WinListType));
4331 WinListType.tp_name = "vim.windowlist";
4332 WinListType.tp_basicsize = sizeof(WinListType);
4333 WinListType.tp_as_sequence = &WinListAsSeq;
4334 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
4335 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004336 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004337
4338 vim_memset(&TabListType, 0, sizeof(TabListType));
4339 TabListType.tp_name = "vim.tabpagelist";
4340 TabListType.tp_basicsize = sizeof(TabListType);
4341 TabListType.tp_as_sequence = &TabListAsSeq;
4342 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
4343 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004344
4345 vim_memset(&RangeType, 0, sizeof(RangeType));
4346 RangeType.tp_name = "vim.range";
4347 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004348 RangeType.tp_dealloc = (destructor)RangeDestructor;
4349 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004350 RangeType.tp_as_sequence = &RangeAsSeq;
4351 RangeType.tp_as_mapping = &RangeAsMapping;
4352 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
4353 RangeType.tp_doc = "vim Range object";
4354 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004355 RangeType.tp_traverse = (traverseproc)RangeTraverse;
4356 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004357#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004358 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004359 RangeType.tp_alloc = call_PyType_GenericAlloc;
4360 RangeType.tp_new = call_PyType_GenericNew;
4361 RangeType.tp_free = call_PyObject_Free;
4362#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004363 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004364#endif
4365
4366 vim_memset(&CurrentType, 0, sizeof(CurrentType));
4367 CurrentType.tp_name = "vim.currentdata";
4368 CurrentType.tp_basicsize = sizeof(CurrentObject);
4369 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
4370 CurrentType.tp_doc = "vim current object";
4371#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004372 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
4373 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004374#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004375 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
4376 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004377#endif
4378
4379 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
4380 DictionaryType.tp_name = "vim.dictionary";
4381 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004382 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004383 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
4384 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
4385 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
4386 DictionaryType.tp_methods = DictionaryMethods;
4387#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004388 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
4389 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004390#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004391 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
4392 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004393#endif
4394
4395 vim_memset(&ListType, 0, sizeof(ListType));
4396 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004397 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004398 ListType.tp_basicsize = sizeof(ListObject);
4399 ListType.tp_as_sequence = &ListAsSeq;
4400 ListType.tp_as_mapping = &ListAsMapping;
4401 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
4402 ListType.tp_doc = "list pushing modifications to vim structure";
4403 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004404 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004405#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004406 ListType.tp_getattro = (getattrofunc)ListGetattro;
4407 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004408#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004409 ListType.tp_getattr = (getattrfunc)ListGetattr;
4410 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004411#endif
4412
4413 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004414 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004415 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004416 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
4417 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004418 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
4419 FunctionType.tp_doc = "object that calls vim function";
4420 FunctionType.tp_methods = FunctionMethods;
4421#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004422 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004423#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004424 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004425#endif
4426
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004427 vim_memset(&OptionsType, 0, sizeof(OptionsType));
4428 OptionsType.tp_name = "vim.options";
4429 OptionsType.tp_basicsize = sizeof(OptionsObject);
4430 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
4431 OptionsType.tp_doc = "object for manipulating options";
4432 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004433 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
4434 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
4435 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004436
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004437#if PY_MAJOR_VERSION >= 3
4438 vim_memset(&vimmodule, 0, sizeof(vimmodule));
4439 vimmodule.m_name = "vim";
4440 vimmodule.m_doc = "Vim Python interface\n";
4441 vimmodule.m_size = -1;
4442 vimmodule.m_methods = VimMethods;
4443#endif
4444}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004445
4446#define PYTYPE_READY(type) \
4447 if (PyType_Ready(&type)) \
4448 return -1;
4449
4450 static int
4451init_types()
4452{
4453 PYTYPE_READY(IterType);
4454 PYTYPE_READY(BufferType);
4455 PYTYPE_READY(RangeType);
4456 PYTYPE_READY(WindowType);
4457 PYTYPE_READY(TabPageType);
4458 PYTYPE_READY(BufMapType);
4459 PYTYPE_READY(WinListType);
4460 PYTYPE_READY(TabListType);
4461 PYTYPE_READY(CurrentType);
4462 PYTYPE_READY(DictionaryType);
4463 PYTYPE_READY(ListType);
4464 PYTYPE_READY(FunctionType);
4465 PYTYPE_READY(OptionsType);
4466 PYTYPE_READY(OutputType);
4467 return 0;
4468}
4469
4470static BufMapObject TheBufferMap =
4471{
4472 PyObject_HEAD_INIT(&BufMapType)
4473};
4474
4475static WinListObject TheWindowList =
4476{
4477 PyObject_HEAD_INIT(&WinListType)
4478 NULL
4479};
4480
4481static CurrentObject TheCurrent =
4482{
4483 PyObject_HEAD_INIT(&CurrentType)
4484};
4485
4486static TabListObject TheTabPageList =
4487{
4488 PyObject_HEAD_INIT(&TabListType)
4489};
4490
4491static struct numeric_constant {
4492 char *name;
4493 int value;
4494} numeric_constants[] = {
4495 {"VAR_LOCKED", VAR_LOCKED},
4496 {"VAR_FIXED", VAR_FIXED},
4497 {"VAR_SCOPE", VAR_SCOPE},
4498 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
4499};
4500
4501static struct object_constant {
4502 char *name;
4503 PyObject *value;
4504} object_constants[] = {
4505 {"buffers", (PyObject *)(void *)&TheBufferMap},
4506 {"windows", (PyObject *)(void *)&TheWindowList},
4507 {"tabpages", (PyObject *)(void *)&TheTabPageList},
4508 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02004509
4510 {"Buffer", (PyObject *)&BufferType},
4511 {"Range", (PyObject *)&RangeType},
4512 {"Window", (PyObject *)&WindowType},
4513 {"TabPage", (PyObject *)&TabPageType},
4514 {"Dictionary", (PyObject *)&DictionaryType},
4515 {"List", (PyObject *)&ListType},
4516 {"Function", (PyObject *)&FunctionType},
4517 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004518};
4519
4520typedef int (*object_adder)(PyObject *, const char *, PyObject *);
4521
4522#define ADD_OBJECT(m, name, obj) \
4523 if (add_object(m, name, obj)) \
4524 return -1;
4525
4526#define ADD_CHECKED_OBJECT(m, name, obj) \
4527 { \
4528 PyObject *value = obj; \
4529 if (!value) \
4530 return -1; \
4531 ADD_OBJECT(m, name, value); \
4532 }
4533
4534 static int
4535populate_module(PyObject *m, object_adder add_object)
4536{
4537 int i;
4538
4539 for (i = 0; i < (int)(sizeof(numeric_constants)
4540 / sizeof(struct numeric_constant));
4541 ++i)
4542 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
4543 PyInt_FromLong(numeric_constants[i].value));
4544
4545 for (i = 0; i < (int)(sizeof(object_constants)
4546 / sizeof(struct object_constant));
4547 ++i)
4548 {
4549 PyObject *value;
4550
4551 value = object_constants[i].value;
4552 Py_INCREF(value);
4553 ADD_OBJECT(m, object_constants[i].name, value);
4554 }
4555
4556 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
4557 return -1;
4558 ADD_OBJECT(m, "error", VimError);
4559
4560 ADD_CHECKED_OBJECT(m, "vars", DictionaryNew(&globvardict));
4561 ADD_CHECKED_OBJECT(m, "vvars", DictionaryNew(&vimvardict));
4562 ADD_CHECKED_OBJECT(m, "options",
4563 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
4564 return 0;
4565}