blob: 2098ed1f0d7c63375a1c7b7b4ec67c86aa8dfcf9 [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 Moolenaard6e39182013-05-21 18:30:34 +02001818TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001819{
1820 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001821 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001822 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001823 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001824 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001825 return DictionaryNew(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001826 else if (strcmp(name, "window") == 0)
1827 {
1828 /* For current tab window.c does not bother to set or update tp_curwin
1829 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001830 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001831 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001832 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001833 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001834 }
1835 return NULL;
1836}
1837
1838 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001839TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001840{
1841 static char repr[100];
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001842
Bram Moolenaard6e39182013-05-21 18:30:34 +02001843 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001844 {
1845 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
1846 return PyString_FromString(repr);
1847 }
1848 else
1849 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001850 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001851
1852 if (t == 0)
1853 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
1854 (self));
1855 else
1856 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
1857
1858 return PyString_FromString(repr);
1859 }
1860}
1861
1862static struct PyMethodDef TabPageMethods[] = {
1863 /* name, function, calling, documentation */
1864 { NULL, NULL, 0, NULL }
1865};
1866
1867/*
1868 * Window list object
1869 */
1870
1871static PyTypeObject TabListType;
1872static PySequenceMethods TabListAsSeq;
1873
1874typedef struct
1875{
1876 PyObject_HEAD
1877} TabListObject;
1878
1879 static PyInt
1880TabListLength(PyObject *self UNUSED)
1881{
1882 tabpage_T *tp = first_tabpage;
1883 PyInt n = 0;
1884
1885 while (tp != NULL)
1886 {
1887 ++n;
1888 tp = tp->tp_next;
1889 }
1890
1891 return n;
1892}
1893
1894 static PyObject *
1895TabListItem(PyObject *self UNUSED, PyInt n)
1896{
1897 tabpage_T *tp;
1898
1899 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
1900 if (n == 0)
1901 return TabPageNew(tp);
1902
1903 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
1904 return NULL;
1905}
1906
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001907/* Window object
1908 */
1909
1910typedef struct
1911{
1912 PyObject_HEAD
1913 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001914 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001915} WindowObject;
1916
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001917static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001918
1919 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001920CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001921{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001922 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001923 {
1924 PyErr_SetVim(_("attempt to refer to deleted window"));
1925 return -1;
1926 }
1927
1928 return 0;
1929}
1930
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001931 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001932WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02001933{
1934 /* We need to handle deletion of windows underneath us.
1935 * If we add a "w_python*_ref" field to the win_T structure,
1936 * then we can get at it in win_free() in vim. We then
1937 * need to create only ONE Python object per window - if
1938 * we try to create a second, just INCREF the existing one
1939 * and return it. The (single) Python object referring to
1940 * the window is stored in "w_python*_ref".
1941 * On a win_free() we set the Python object's win_T* field
1942 * to an invalid value. We trap all uses of a window
1943 * object, and reject them if the win_T* field is invalid.
1944 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001945 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02001946 * w_python_ref and w_python3_ref fields respectively.
1947 */
1948
1949 WindowObject *self;
1950
1951 if (WIN_PYTHON_REF(win))
1952 {
1953 self = WIN_PYTHON_REF(win);
1954 Py_INCREF(self);
1955 }
1956 else
1957 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02001958 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02001959 if (self == NULL)
1960 return NULL;
1961 self->win = win;
1962 WIN_PYTHON_REF(win) = self;
1963 }
1964
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001965 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
1966
Bram Moolenaar971db462013-05-12 18:44:48 +02001967 return (PyObject *)(self);
1968}
1969
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001970 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001971WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001972{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001973 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02001974 if (self->win && self->win != INVALID_WINDOW_VALUE)
1975 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02001976 Py_XDECREF(((PyObject *)(self->tabObject)));
1977 PyObject_GC_Del((void *)(self));
1978}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001979
Bram Moolenaar774267b2013-05-21 20:51:59 +02001980 static int
1981WindowTraverse(WindowObject *self, visitproc visit, void *arg)
1982{
1983 Py_VISIT(((PyObject *)(self->tabObject)));
1984 return 0;
1985}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001986
Bram Moolenaar774267b2013-05-21 20:51:59 +02001987 static int
1988WindowClear(WindowObject *self)
1989{
1990 Py_CLEAR(self->tabObject);
1991 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001992}
1993
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001994 static win_T *
1995get_firstwin(TabPageObject *tabObject)
1996{
1997 if (tabObject)
1998 {
1999 if (CheckTabPage(tabObject))
2000 return NULL;
2001 /* For current tab window.c does not bother to set or update tp_firstwin
2002 */
2003 else if (tabObject->tab == curtab)
2004 return firstwin;
2005 else
2006 return tabObject->tab->tp_firstwin;
2007 }
2008 else
2009 return firstwin;
2010}
2011
Bram Moolenaar971db462013-05-12 18:44:48 +02002012 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002013WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002014{
2015 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002016 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002017 else if (strcmp(name, "cursor") == 0)
2018 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002019 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002020
2021 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2022 }
2023 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002024 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002025#ifdef FEAT_WINDOWS
2026 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002027 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002028#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002029#ifdef FEAT_VERTSPLIT
2030 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002031 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002032 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002033 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002034#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02002035 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002036 return DictionaryNew(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002037 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002038 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
2039 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02002040 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002041 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002042 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002043 return NULL;
2044 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002045 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002046 }
2047 else if (strcmp(name, "tabpage") == 0)
2048 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002049 Py_INCREF(self->tabObject);
2050 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002051 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002052 else if (strcmp(name,"__members__") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002053 return Py_BuildValue("[sssssssss]", "buffer", "cursor", "height",
2054 "vars", "options", "number", "row", "col", "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002055 else
2056 return NULL;
2057}
2058
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002059 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002060WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002061{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002062 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002063 return -1;
2064
2065 if (strcmp(name, "buffer") == 0)
2066 {
2067 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2068 return -1;
2069 }
2070 else if (strcmp(name, "cursor") == 0)
2071 {
2072 long lnum;
2073 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002074
2075 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2076 return -1;
2077
Bram Moolenaard6e39182013-05-21 18:30:34 +02002078 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002079 {
2080 PyErr_SetVim(_("cursor position outside buffer"));
2081 return -1;
2082 }
2083
2084 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002085 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002086 return -1;
2087
Bram Moolenaard6e39182013-05-21 18:30:34 +02002088 self->win->w_cursor.lnum = lnum;
2089 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002090#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02002091 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002092#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002093 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002094 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002095
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002096 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002097 return 0;
2098 }
2099 else if (strcmp(name, "height") == 0)
2100 {
2101 int height;
2102 win_T *savewin;
2103
2104 if (!PyArg_Parse(val, "i", &height))
2105 return -1;
2106
2107#ifdef FEAT_GUI
2108 need_mouse_correct = TRUE;
2109#endif
2110 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002111 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002112
2113 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002114 win_setheight(height);
2115 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002116 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002117 return -1;
2118
2119 return 0;
2120 }
2121#ifdef FEAT_VERTSPLIT
2122 else if (strcmp(name, "width") == 0)
2123 {
2124 int width;
2125 win_T *savewin;
2126
2127 if (!PyArg_Parse(val, "i", &width))
2128 return -1;
2129
2130#ifdef FEAT_GUI
2131 need_mouse_correct = TRUE;
2132#endif
2133 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002134 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002135
2136 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002137 win_setwidth(width);
2138 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002139 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002140 return -1;
2141
2142 return 0;
2143 }
2144#endif
2145 else
2146 {
2147 PyErr_SetString(PyExc_AttributeError, name);
2148 return -1;
2149 }
2150}
2151
2152 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002153WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002154{
2155 static char repr[100];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002156
Bram Moolenaard6e39182013-05-21 18:30:34 +02002157 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002158 {
2159 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2160 return PyString_FromString(repr);
2161 }
2162 else
2163 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002164 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002165
Bram Moolenaar6d216452013-05-12 19:00:41 +02002166 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002167 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2168 (self));
2169 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02002170 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002171
2172 return PyString_FromString(repr);
2173 }
2174}
2175
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002176static struct PyMethodDef WindowMethods[] = {
2177 /* name, function, calling, documentation */
2178 { NULL, NULL, 0, NULL }
2179};
2180
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002181/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002182 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002183 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002184
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002185static PyTypeObject WinListType;
2186static PySequenceMethods WinListAsSeq;
2187
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002188typedef struct
2189{
2190 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002191 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002192} WinListObject;
2193
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002194 static PyObject *
2195WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002196{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002197 WinListObject *self;
2198
2199 self = PyObject_NEW(WinListObject, &WinListType);
2200 self->tabObject = tabObject;
2201 Py_INCREF(tabObject);
2202
2203 return (PyObject *)(self);
2204}
2205
2206 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002207WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002208{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002209 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002210
2211 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02002212 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002213 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02002214 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002215
2216 DESTRUCTOR_FINISH(self);
2217}
2218
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002219 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002220WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002221{
2222 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002223 PyInt n = 0;
2224
Bram Moolenaard6e39182013-05-21 18:30:34 +02002225 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002226 return -1;
2227
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002228 while (w != NULL)
2229 {
2230 ++n;
2231 w = W_NEXT(w);
2232 }
2233
2234 return n;
2235}
2236
2237 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002238WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002239{
2240 win_T *w;
2241
Bram Moolenaard6e39182013-05-21 18:30:34 +02002242 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002243 return NULL;
2244
2245 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002246 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002247 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002248
2249 PyErr_SetString(PyExc_IndexError, _("no such window"));
2250 return NULL;
2251}
2252
2253/* Convert a Python string into a Vim line.
2254 *
2255 * The result is in allocated memory. All internal nulls are replaced by
2256 * newline characters. It is an error for the string to contain newline
2257 * characters.
2258 *
2259 * On errors, the Python exception data is set, and NULL is returned.
2260 */
2261 static char *
2262StringToLine(PyObject *obj)
2263{
2264 const char *str;
2265 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002266 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002267 PyInt len;
2268 PyInt i;
2269 char *p;
2270
2271 if (obj == NULL || !PyString_Check(obj))
2272 {
2273 PyErr_BadArgument();
2274 return NULL;
2275 }
2276
Bram Moolenaar19e60942011-06-19 00:27:51 +02002277 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2278 str = PyString_AsString(bytes);
2279 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002280
2281 /*
2282 * Error checking: String must not contain newlines, as we
2283 * are replacing a single line, and we must replace it with
2284 * a single line.
2285 * A trailing newline is removed, so that append(f.readlines()) works.
2286 */
2287 p = memchr(str, '\n', len);
2288 if (p != NULL)
2289 {
2290 if (p == str + len - 1)
2291 --len;
2292 else
2293 {
2294 PyErr_SetVim(_("string cannot contain newlines"));
2295 return NULL;
2296 }
2297 }
2298
2299 /* Create a copy of the string, with internal nulls replaced by
2300 * newline characters, as is the vim convention.
2301 */
2302 save = (char *)alloc((unsigned)(len+1));
2303 if (save == NULL)
2304 {
2305 PyErr_NoMemory();
2306 return NULL;
2307 }
2308
2309 for (i = 0; i < len; ++i)
2310 {
2311 if (str[i] == '\0')
2312 save[i] = '\n';
2313 else
2314 save[i] = str[i];
2315 }
2316
2317 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002318 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002319
2320 return save;
2321}
2322
2323/* Get a line from the specified buffer. The line number is
2324 * in Vim format (1-based). The line is returned as a Python
2325 * string object.
2326 */
2327 static PyObject *
2328GetBufferLine(buf_T *buf, PyInt n)
2329{
2330 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2331}
2332
2333
2334/* Get a list of lines from the specified buffer. The line numbers
2335 * are in Vim format (1-based). The range is from lo up to, but not
2336 * including, hi. The list is returned as a Python list of string objects.
2337 */
2338 static PyObject *
2339GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2340{
2341 PyInt i;
2342 PyInt n = hi - lo;
2343 PyObject *list = PyList_New(n);
2344
2345 if (list == NULL)
2346 return NULL;
2347
2348 for (i = 0; i < n; ++i)
2349 {
2350 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2351
2352 /* Error check - was the Python string creation OK? */
2353 if (str == NULL)
2354 {
2355 Py_DECREF(list);
2356 return NULL;
2357 }
2358
2359 /* Set the list item */
2360 if (PyList_SetItem(list, i, str))
2361 {
2362 Py_DECREF(str);
2363 Py_DECREF(list);
2364 return NULL;
2365 }
2366 }
2367
2368 /* The ownership of the Python list is passed to the caller (ie,
2369 * the caller should Py_DECREF() the object when it is finished
2370 * with it).
2371 */
2372
2373 return list;
2374}
2375
2376/*
2377 * Check if deleting lines made the cursor position invalid.
2378 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2379 * deleted).
2380 */
2381 static void
2382py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2383{
2384 if (curwin->w_cursor.lnum >= lo)
2385 {
2386 /* Adjust the cursor position if it's in/after the changed
2387 * lines. */
2388 if (curwin->w_cursor.lnum >= hi)
2389 {
2390 curwin->w_cursor.lnum += extra;
2391 check_cursor_col();
2392 }
2393 else if (extra < 0)
2394 {
2395 curwin->w_cursor.lnum = lo;
2396 check_cursor();
2397 }
2398 else
2399 check_cursor_col();
2400 changed_cline_bef_curs();
2401 }
2402 invalidate_botline();
2403}
2404
Bram Moolenaar19e60942011-06-19 00:27:51 +02002405/*
2406 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002407 * in Vim format (1-based). The replacement line is given as
2408 * a Python string object. The object is checked for validity
2409 * and correct format. Errors are returned as a value of FAIL.
2410 * The return value is OK on success.
2411 * If OK is returned and len_change is not NULL, *len_change
2412 * is set to the change in the buffer length.
2413 */
2414 static int
2415SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2416{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002417 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002418 * There are three cases:
2419 * 1. NULL, or None - this is a deletion.
2420 * 2. A string - this is a replacement.
2421 * 3. Anything else - this is an error.
2422 */
2423 if (line == Py_None || line == NULL)
2424 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002425 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002426
2427 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002428 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002429
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002430 VimTryStart();
2431
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002432 if (u_savedel((linenr_T)n, 1L) == FAIL)
2433 PyErr_SetVim(_("cannot save undo information"));
2434 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2435 PyErr_SetVim(_("cannot delete line"));
2436 else
2437 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002438 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002439 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2440 deleted_lines_mark((linenr_T)n, 1L);
2441 }
2442
Bram Moolenaar105bc352013-05-17 16:03:57 +02002443 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002444
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002445 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002446 return FAIL;
2447
2448 if (len_change)
2449 *len_change = -1;
2450
2451 return OK;
2452 }
2453 else if (PyString_Check(line))
2454 {
2455 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002456 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002457
2458 if (save == NULL)
2459 return FAIL;
2460
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002461 VimTryStart();
2462
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002463 /* We do not need to free "save" if ml_replace() consumes it. */
2464 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002465 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002466
2467 if (u_savesub((linenr_T)n) == FAIL)
2468 {
2469 PyErr_SetVim(_("cannot save undo information"));
2470 vim_free(save);
2471 }
2472 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2473 {
2474 PyErr_SetVim(_("cannot replace line"));
2475 vim_free(save);
2476 }
2477 else
2478 changed_bytes((linenr_T)n, 0);
2479
Bram Moolenaar105bc352013-05-17 16:03:57 +02002480 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002481
2482 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02002483 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002484 check_cursor_col();
2485
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002486 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002487 return FAIL;
2488
2489 if (len_change)
2490 *len_change = 0;
2491
2492 return OK;
2493 }
2494 else
2495 {
2496 PyErr_BadArgument();
2497 return FAIL;
2498 }
2499}
2500
Bram Moolenaar19e60942011-06-19 00:27:51 +02002501/* Replace a range of lines in the specified buffer. The line numbers are in
2502 * Vim format (1-based). The range is from lo up to, but not including, hi.
2503 * The replacement lines are given as a Python list of string objects. The
2504 * list is checked for validity and correct format. Errors are returned as a
2505 * value of FAIL. The return value is OK on success.
2506 * If OK is returned and len_change is not NULL, *len_change
2507 * is set to the change in the buffer length.
2508 */
2509 static int
2510SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2511{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002512 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002513 * There are three cases:
2514 * 1. NULL, or None - this is a deletion.
2515 * 2. A list - this is a replacement.
2516 * 3. Anything else - this is an error.
2517 */
2518 if (list == Py_None || list == NULL)
2519 {
2520 PyInt i;
2521 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002522 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002523
2524 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002525 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002526 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002527
2528 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2529 PyErr_SetVim(_("cannot save undo information"));
2530 else
2531 {
2532 for (i = 0; i < n; ++i)
2533 {
2534 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2535 {
2536 PyErr_SetVim(_("cannot delete line"));
2537 break;
2538 }
2539 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02002540 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002541 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2542 deleted_lines_mark((linenr_T)lo, (long)i);
2543 }
2544
Bram Moolenaar105bc352013-05-17 16:03:57 +02002545 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002546
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002547 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002548 return FAIL;
2549
2550 if (len_change)
2551 *len_change = -n;
2552
2553 return OK;
2554 }
2555 else if (PyList_Check(list))
2556 {
2557 PyInt i;
2558 PyInt new_len = PyList_Size(list);
2559 PyInt old_len = hi - lo;
2560 PyInt extra = 0; /* lines added to text, can be negative */
2561 char **array;
2562 buf_T *savebuf;
2563
2564 if (new_len == 0) /* avoid allocating zero bytes */
2565 array = NULL;
2566 else
2567 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002568 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002569 if (array == NULL)
2570 {
2571 PyErr_NoMemory();
2572 return FAIL;
2573 }
2574 }
2575
2576 for (i = 0; i < new_len; ++i)
2577 {
2578 PyObject *line = PyList_GetItem(list, i);
2579
2580 array[i] = StringToLine(line);
2581 if (array[i] == NULL)
2582 {
2583 while (i)
2584 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002585 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002586 return FAIL;
2587 }
2588 }
2589
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002590 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02002591 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002592
2593 // START of region without "return". Must call restore_buffer()!
2594 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002595
2596 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2597 PyErr_SetVim(_("cannot save undo information"));
2598
2599 /* If the size of the range is reducing (ie, new_len < old_len) we
2600 * need to delete some old_len. We do this at the start, by
2601 * repeatedly deleting line "lo".
2602 */
2603 if (!PyErr_Occurred())
2604 {
2605 for (i = 0; i < old_len - new_len; ++i)
2606 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2607 {
2608 PyErr_SetVim(_("cannot delete line"));
2609 break;
2610 }
2611 extra -= i;
2612 }
2613
2614 /* For as long as possible, replace the existing old_len with the
2615 * new old_len. This is a more efficient operation, as it requires
2616 * less memory allocation and freeing.
2617 */
2618 if (!PyErr_Occurred())
2619 {
2620 for (i = 0; i < old_len && i < new_len; ++i)
2621 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2622 == FAIL)
2623 {
2624 PyErr_SetVim(_("cannot replace line"));
2625 break;
2626 }
2627 }
2628 else
2629 i = 0;
2630
2631 /* Now we may need to insert the remaining new old_len. If we do, we
2632 * must free the strings as we finish with them (we can't pass the
2633 * responsibility to vim in this case).
2634 */
2635 if (!PyErr_Occurred())
2636 {
2637 while (i < new_len)
2638 {
2639 if (ml_append((linenr_T)(lo + i - 1),
2640 (char_u *)array[i], 0, FALSE) == FAIL)
2641 {
2642 PyErr_SetVim(_("cannot insert line"));
2643 break;
2644 }
2645 vim_free(array[i]);
2646 ++i;
2647 ++extra;
2648 }
2649 }
2650
2651 /* Free any left-over old_len, as a result of an error */
2652 while (i < new_len)
2653 {
2654 vim_free(array[i]);
2655 ++i;
2656 }
2657
2658 /* Free the array of old_len. All of its contents have now
2659 * been dealt with (either freed, or the responsibility passed
2660 * to vim.
2661 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002662 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002663
2664 /* Adjust marks. Invalidate any which lie in the
2665 * changed range, and move any in the remainder of the buffer.
2666 */
2667 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2668 (long)MAXLNUM, (long)extra);
2669 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2670
Bram Moolenaar105bc352013-05-17 16:03:57 +02002671 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002672 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2673
Bram Moolenaar105bc352013-05-17 16:03:57 +02002674 // END of region without "return".
2675 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002676
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002677 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002678 return FAIL;
2679
2680 if (len_change)
2681 *len_change = new_len - old_len;
2682
2683 return OK;
2684 }
2685 else
2686 {
2687 PyErr_BadArgument();
2688 return FAIL;
2689 }
2690}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002691
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002692/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002693 * The line number is in Vim format (1-based). The lines to be inserted are
2694 * given as a Python list of string objects or as a single string. The lines
2695 * to be added are checked for validity and correct format. Errors are
2696 * returned as a value of FAIL. The return value is OK on success.
2697 * If OK is returned and len_change is not NULL, *len_change
2698 * is set to the change in the buffer length.
2699 */
2700 static int
2701InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2702{
2703 /* First of all, we check the type of the supplied Python object.
2704 * It must be a string or a list, or the call is in error.
2705 */
2706 if (PyString_Check(lines))
2707 {
2708 char *str = StringToLine(lines);
2709 buf_T *savebuf;
2710
2711 if (str == NULL)
2712 return FAIL;
2713
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002714 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002715 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002716 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002717
2718 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2719 PyErr_SetVim(_("cannot save undo information"));
2720 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2721 PyErr_SetVim(_("cannot insert line"));
2722 else
2723 appended_lines_mark((linenr_T)n, 1L);
2724
2725 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002726 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002727 update_screen(VALID);
2728
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002729 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002730 return FAIL;
2731
2732 if (len_change)
2733 *len_change = 1;
2734
2735 return OK;
2736 }
2737 else if (PyList_Check(lines))
2738 {
2739 PyInt i;
2740 PyInt size = PyList_Size(lines);
2741 char **array;
2742 buf_T *savebuf;
2743
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002744 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002745 if (array == NULL)
2746 {
2747 PyErr_NoMemory();
2748 return FAIL;
2749 }
2750
2751 for (i = 0; i < size; ++i)
2752 {
2753 PyObject *line = PyList_GetItem(lines, i);
2754 array[i] = StringToLine(line);
2755
2756 if (array[i] == NULL)
2757 {
2758 while (i)
2759 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002760 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002761 return FAIL;
2762 }
2763 }
2764
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002765 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002766 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002767 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002768
2769 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2770 PyErr_SetVim(_("cannot save undo information"));
2771 else
2772 {
2773 for (i = 0; i < size; ++i)
2774 {
2775 if (ml_append((linenr_T)(n + i),
2776 (char_u *)array[i], 0, FALSE) == FAIL)
2777 {
2778 PyErr_SetVim(_("cannot insert line"));
2779
2780 /* Free the rest of the lines */
2781 while (i < size)
2782 vim_free(array[i++]);
2783
2784 break;
2785 }
2786 vim_free(array[i]);
2787 }
2788 if (i > 0)
2789 appended_lines_mark((linenr_T)n, (long)i);
2790 }
2791
2792 /* Free the array of lines. All of its contents have now
2793 * been freed.
2794 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002795 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002796
Bram Moolenaar105bc352013-05-17 16:03:57 +02002797 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002798 update_screen(VALID);
2799
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002800 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002801 return FAIL;
2802
2803 if (len_change)
2804 *len_change = size;
2805
2806 return OK;
2807 }
2808 else
2809 {
2810 PyErr_BadArgument();
2811 return FAIL;
2812 }
2813}
2814
2815/*
2816 * Common routines for buffers and line ranges
2817 * -------------------------------------------
2818 */
2819
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002820typedef struct
2821{
2822 PyObject_HEAD
2823 buf_T *buf;
2824} BufferObject;
2825
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002826 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002827CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002828{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002829 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002830 {
2831 PyErr_SetVim(_("attempt to refer to deleted buffer"));
2832 return -1;
2833 }
2834
2835 return 0;
2836}
2837
2838 static PyObject *
2839RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
2840{
2841 if (CheckBuffer(self))
2842 return NULL;
2843
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002844 if (end == -1)
2845 end = self->buf->b_ml.ml_line_count;
2846
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002847 if (n < 0)
2848 n += end - start + 1;
2849
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002850 if (n < 0 || n > end - start)
2851 {
2852 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2853 return NULL;
2854 }
2855
2856 return GetBufferLine(self->buf, n+start);
2857}
2858
2859 static PyObject *
2860RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
2861{
2862 PyInt size;
2863
2864 if (CheckBuffer(self))
2865 return NULL;
2866
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002867 if (end == -1)
2868 end = self->buf->b_ml.ml_line_count;
2869
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002870 size = end - start + 1;
2871
2872 if (lo < 0)
2873 lo = 0;
2874 else if (lo > size)
2875 lo = size;
2876 if (hi < 0)
2877 hi = 0;
2878 if (hi < lo)
2879 hi = lo;
2880 else if (hi > size)
2881 hi = size;
2882
2883 return GetBufferLineList(self->buf, lo+start, hi+start);
2884}
2885
2886 static PyInt
2887RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2888{
2889 PyInt len_change;
2890
2891 if (CheckBuffer(self))
2892 return -1;
2893
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002894 if (end == -1)
2895 end = self->buf->b_ml.ml_line_count;
2896
Bram Moolenaarbd80f352013-05-12 21:16:23 +02002897 if (n < 0)
2898 n += end - start + 1;
2899
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002900 if (n < 0 || n > end - start)
2901 {
2902 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
2903 return -1;
2904 }
2905
2906 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
2907 return -1;
2908
2909 if (new_end)
2910 *new_end = end + len_change;
2911
2912 return 0;
2913}
2914
Bram Moolenaar19e60942011-06-19 00:27:51 +02002915 static PyInt
2916RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
2917{
2918 PyInt size;
2919 PyInt len_change;
2920
2921 /* Self must be a valid buffer */
2922 if (CheckBuffer(self))
2923 return -1;
2924
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002925 if (end == -1)
2926 end = self->buf->b_ml.ml_line_count;
2927
Bram Moolenaar19e60942011-06-19 00:27:51 +02002928 /* Sort out the slice range */
2929 size = end - start + 1;
2930
2931 if (lo < 0)
2932 lo = 0;
2933 else if (lo > size)
2934 lo = size;
2935 if (hi < 0)
2936 hi = 0;
2937 if (hi < lo)
2938 hi = lo;
2939 else if (hi > size)
2940 hi = size;
2941
2942 if (SetBufferLineList(self->buf, lo + start, hi + start,
2943 val, &len_change) == FAIL)
2944 return -1;
2945
2946 if (new_end)
2947 *new_end = end + len_change;
2948
2949 return 0;
2950}
2951
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002952
2953 static PyObject *
2954RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
2955{
2956 PyObject *lines;
2957 PyInt len_change;
2958 PyInt max;
2959 PyInt n;
2960
2961 if (CheckBuffer(self))
2962 return NULL;
2963
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02002964 if (end == -1)
2965 end = self->buf->b_ml.ml_line_count;
2966
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002967 max = n = end - start + 1;
2968
2969 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
2970 return NULL;
2971
2972 if (n < 0 || n > max)
2973 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02002974 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002975 return NULL;
2976 }
2977
2978 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
2979 return NULL;
2980
2981 if (new_end)
2982 *new_end = end + len_change;
2983
2984 Py_INCREF(Py_None);
2985 return Py_None;
2986}
2987
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002988/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002989 */
2990
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002991static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002992static PySequenceMethods RangeAsSeq;
2993static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002994
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002995typedef struct
2996{
2997 PyObject_HEAD
2998 BufferObject *buf;
2999 PyInt start;
3000 PyInt end;
3001} RangeObject;
3002
3003 static PyObject *
3004RangeNew(buf_T *buf, PyInt start, PyInt end)
3005{
3006 BufferObject *bufr;
3007 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003008 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003009 if (self == NULL)
3010 return NULL;
3011
3012 bufr = (BufferObject *)BufferNew(buf);
3013 if (bufr == NULL)
3014 {
3015 Py_DECREF(self);
3016 return NULL;
3017 }
3018 Py_INCREF(bufr);
3019
3020 self->buf = bufr;
3021 self->start = start;
3022 self->end = end;
3023
3024 return (PyObject *)(self);
3025}
3026
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003027 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003028RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003029{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003030 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003031 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02003032 PyObject_GC_Del((void *)(self));
3033}
3034
3035 static int
3036RangeTraverse(RangeObject *self, visitproc visit, void *arg)
3037{
3038 Py_VISIT(((PyObject *)(self->buf)));
3039 return 0;
3040}
3041
3042 static int
3043RangeClear(RangeObject *self)
3044{
3045 Py_CLEAR(self->buf);
3046 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003047}
3048
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003049 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003050RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003051{
3052 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003053 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003054 return -1; /* ??? */
3055
Bram Moolenaard6e39182013-05-21 18:30:34 +02003056 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003057}
3058
3059 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003060RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003061{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003062 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003063}
3064
3065 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003066RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003067{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003068 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003069}
3070
3071 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003072RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003073{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003074 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003075}
3076
3077 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003078RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003079{
3080 static char repr[100];
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003081
Bram Moolenaard6e39182013-05-21 18:30:34 +02003082 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003083 {
3084 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
3085 (self));
3086 return PyString_FromString(repr);
3087 }
3088 else
3089 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003090 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003091 int len;
3092
3093 if (name == NULL)
3094 name = "";
3095 len = (int)strlen(name);
3096
3097 if (len > 45)
3098 name = name + (45 - len);
3099
3100 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
3101 len > 45 ? "..." : "", name,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003102 self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003103
3104 return PyString_FromString(repr);
3105 }
3106}
3107
3108static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003109 /* name, function, calling, documentation */
3110 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
3111 { NULL, NULL, 0, NULL }
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003112};
3113
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003114static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003115static PySequenceMethods BufferAsSeq;
3116static PyMappingMethods BufferAsMapping;
3117
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003118 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02003119BufferNew(buf_T *buf)
3120{
3121 /* We need to handle deletion of buffers underneath us.
3122 * If we add a "b_python*_ref" field to the buf_T structure,
3123 * then we can get at it in buf_freeall() in vim. We then
3124 * need to create only ONE Python object per buffer - if
3125 * we try to create a second, just INCREF the existing one
3126 * and return it. The (single) Python object referring to
3127 * the buffer is stored in "b_python*_ref".
3128 * Question: what to do on a buf_freeall(). We'll probably
3129 * have to either delete the Python object (DECREF it to
3130 * zero - a bad idea, as it leaves dangling refs!) or
3131 * set the buf_T * value to an invalid value (-1?), which
3132 * means we need checks in all access functions... Bah.
3133 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003134 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003135 * b_python_ref and b_python3_ref fields respectively.
3136 */
3137
3138 BufferObject *self;
3139
3140 if (BUF_PYTHON_REF(buf) != NULL)
3141 {
3142 self = BUF_PYTHON_REF(buf);
3143 Py_INCREF(self);
3144 }
3145 else
3146 {
3147 self = PyObject_NEW(BufferObject, &BufferType);
3148 if (self == NULL)
3149 return NULL;
3150 self->buf = buf;
3151 BUF_PYTHON_REF(buf) = self;
3152 }
3153
3154 return (PyObject *)(self);
3155}
3156
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003157 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003158BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003159{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003160 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3161 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003162
3163 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003164}
3165
Bram Moolenaar971db462013-05-12 18:44:48 +02003166 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003167BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003168{
3169 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003170 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003171 return -1; /* ??? */
3172
Bram Moolenaard6e39182013-05-21 18:30:34 +02003173 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003174}
3175
3176 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003177BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003178{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003179 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003180}
3181
3182 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003183BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003184{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003185 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003186}
3187
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003188 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003189BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003190{
3191 if (strcmp(name, "name") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003192 return Py_BuildValue("s", self->buf->b_ffname);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003193 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003194 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003195 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003196 return DictionaryNew(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003197 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003198 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3199 (PyObject *) self);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003200 else if (strcmp(name,"__members__") == 0)
3201 return Py_BuildValue("[ssss]", "name", "number", "vars", "options");
3202 else
3203 return NULL;
3204}
3205
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003206 static int
3207BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
3208{
3209 if (CheckBuffer(self))
3210 return -1;
3211
3212 if (strcmp(name, "name") == 0)
3213 {
3214 char_u *val;
3215 aco_save_T aco;
3216 int r;
3217 PyObject *todecref;
3218
3219 if (!(val = StringToChars(valObject, &todecref)))
3220 return -1;
3221
3222 VimTryStart();
3223 /* Using aucmd_*: autocommands will be executed by rename_buffer */
3224 aucmd_prepbuf(&aco, self->buf);
3225 r = rename_buffer(val);
3226 aucmd_restbuf(&aco);
3227 Py_XDECREF(todecref);
3228 if (VimTryEnd())
3229 return -1;
3230
3231 if (r == FAIL)
3232 {
3233 PyErr_SetVim(_("failed to rename buffer"));
3234 return -1;
3235 }
3236 return 0;
3237 }
3238 else
3239 {
3240 PyErr_SetString(PyExc_AttributeError, name);
3241 return -1;
3242 }
3243}
3244
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003245 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003246BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003247{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003248 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003249}
3250
3251 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003252BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003253{
3254 pos_T *posp;
3255 char *pmark;
3256 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02003257 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003258
Bram Moolenaard6e39182013-05-21 18:30:34 +02003259 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003260 return NULL;
3261
3262 if (!PyArg_ParseTuple(args, "s", &pmark))
3263 return NULL;
3264 mark = *pmark;
3265
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003266 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02003267 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003268 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003269 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003270 if (VimTryEnd())
3271 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003272
3273 if (posp == NULL)
3274 {
3275 PyErr_SetVim(_("invalid mark name"));
3276 return NULL;
3277 }
3278
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003279 if (posp->lnum <= 0)
3280 {
3281 /* Or raise an error? */
3282 Py_INCREF(Py_None);
3283 return Py_None;
3284 }
3285
3286 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3287}
3288
3289 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003290BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003291{
3292 PyInt start;
3293 PyInt end;
3294
Bram Moolenaard6e39182013-05-21 18:30:34 +02003295 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003296 return NULL;
3297
3298 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3299 return NULL;
3300
Bram Moolenaard6e39182013-05-21 18:30:34 +02003301 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003302}
3303
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003304 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003305BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003306{
3307 static char repr[100];
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003308
Bram Moolenaard6e39182013-05-21 18:30:34 +02003309 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003310 {
3311 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3312 return PyString_FromString(repr);
3313 }
3314 else
3315 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003316 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003317 PyInt len;
3318
3319 if (name == NULL)
3320 name = "";
3321 len = strlen(name);
3322
3323 if (len > 35)
3324 name = name + (35 - len);
3325
3326 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3327
3328 return PyString_FromString(repr);
3329 }
3330}
3331
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003332static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003333 /* name, function, calling, documentation */
3334 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
3335 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
3336 {"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 +01003337#if PY_VERSION_HEX >= 0x03000000
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003338 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, "List buffer attributes" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01003339#endif
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003340 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003341};
3342
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003343/*
3344 * Buffer list object - Implementation
3345 */
3346
3347static PyTypeObject BufMapType;
3348
3349typedef struct
3350{
3351 PyObject_HEAD
3352} BufMapObject;
3353
3354 static PyInt
3355BufMapLength(PyObject *self UNUSED)
3356{
3357 buf_T *b = firstbuf;
3358 PyInt n = 0;
3359
3360 while (b)
3361 {
3362 ++n;
3363 b = b->b_next;
3364 }
3365
3366 return n;
3367}
3368
3369 static PyObject *
3370BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3371{
3372 buf_T *b;
3373 int bnr;
3374
3375#if PY_MAJOR_VERSION < 3
3376 if (PyInt_Check(keyObject))
3377 bnr = PyInt_AsLong(keyObject);
3378 else
3379#endif
3380 if (PyLong_Check(keyObject))
3381 bnr = PyLong_AsLong(keyObject);
3382 else
3383 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003384 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003385 return NULL;
3386 }
3387
3388 b = buflist_findnr(bnr);
3389
3390 if (b)
3391 return BufferNew(b);
3392 else
3393 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003394 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003395 return NULL;
3396 }
3397}
3398
3399 static void
3400BufMapIterDestruct(PyObject *buffer)
3401{
3402 /* Iteration was stopped before all buffers were processed */
3403 if (buffer)
3404 {
3405 Py_DECREF(buffer);
3406 }
3407}
3408
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003409 static int
3410BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
3411{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003412 if (buffer)
3413 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003414 return 0;
3415}
3416
3417 static int
3418BufMapIterClear(PyObject **buffer)
3419{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003420 if (*buffer)
3421 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003422 return 0;
3423}
3424
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003425 static PyObject *
3426BufMapIterNext(PyObject **buffer)
3427{
3428 PyObject *next;
3429 PyObject *r;
3430
3431 if (!*buffer)
3432 return NULL;
3433
3434 r = *buffer;
3435
3436 if (CheckBuffer((BufferObject *)(r)))
3437 {
3438 *buffer = NULL;
3439 return NULL;
3440 }
3441
3442 if (!((BufferObject *)(r))->buf->b_next)
3443 next = NULL;
3444 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3445 return NULL;
3446 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02003447 /* Do not increment reference: we no longer hold it (decref), but whoever
3448 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003449 return r;
3450}
3451
3452 static PyObject *
3453BufMapIter(PyObject *self UNUSED)
3454{
3455 PyObject *buffer;
3456
3457 buffer = BufferNew(firstbuf);
3458 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003459 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
3460 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003461}
3462
3463static PyMappingMethods BufMapAsMapping = {
3464 (lenfunc) BufMapLength,
3465 (binaryfunc) BufMapItem,
3466 (objobjargproc) 0,
3467};
3468
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003469/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003470 */
3471
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003472 static PyObject *
3473CurrentGetattr(PyObject *self UNUSED, char *name)
3474{
3475 if (strcmp(name, "buffer") == 0)
3476 return (PyObject *)BufferNew(curbuf);
3477 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003478 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003479 else if (strcmp(name, "tabpage") == 0)
3480 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003481 else if (strcmp(name, "line") == 0)
3482 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3483 else if (strcmp(name, "range") == 0)
3484 return RangeNew(curbuf, RangeStart, RangeEnd);
3485 else if (strcmp(name,"__members__") == 0)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003486 return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
3487 "tabpage");
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003488 else
3489 {
3490 PyErr_SetString(PyExc_AttributeError, name);
3491 return NULL;
3492 }
3493}
3494
3495 static int
3496CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3497{
3498 if (strcmp(name, "line") == 0)
3499 {
3500 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3501 return -1;
3502
3503 return 0;
3504 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003505 else if (strcmp(name, "buffer") == 0)
3506 {
3507 int count;
3508
3509 if (value->ob_type != &BufferType)
3510 {
3511 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3512 return -1;
3513 }
3514
3515 if (CheckBuffer((BufferObject *)(value)))
3516 return -1;
3517 count = ((BufferObject *)(value))->buf->b_fnum;
3518
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003519 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003520 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3521 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003522 if (VimTryEnd())
3523 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003524 PyErr_SetVim(_("failed to switch to given buffer"));
3525 return -1;
3526 }
3527
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003528 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003529 }
3530 else if (strcmp(name, "window") == 0)
3531 {
3532 int count;
3533
3534 if (value->ob_type != &WindowType)
3535 {
3536 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3537 return -1;
3538 }
3539
3540 if (CheckWindow((WindowObject *)(value)))
3541 return -1;
3542 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3543
3544 if (!count)
3545 {
3546 PyErr_SetString(PyExc_ValueError,
3547 _("failed to find window in the current tab page"));
3548 return -1;
3549 }
3550
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003551 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003552 win_goto(((WindowObject *)(value))->win);
3553 if (((WindowObject *)(value))->win != curwin)
3554 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003555 if (VimTryEnd())
3556 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003557 PyErr_SetString(PyExc_RuntimeError,
3558 _("did not switch to the specified window"));
3559 return -1;
3560 }
3561
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003562 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003563 }
3564 else if (strcmp(name, "tabpage") == 0)
3565 {
3566 if (value->ob_type != &TabPageType)
3567 {
3568 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3569 return -1;
3570 }
3571
3572 if (CheckTabPage((TabPageObject *)(value)))
3573 return -1;
3574
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003575 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003576 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3577 if (((TabPageObject *)(value))->tab != curtab)
3578 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003579 if (VimTryEnd())
3580 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003581 PyErr_SetString(PyExc_RuntimeError,
3582 _("did not switch to the specified tab page"));
3583 return -1;
3584 }
3585
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003586 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003587 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003588 else
3589 {
3590 PyErr_SetString(PyExc_AttributeError, name);
3591 return -1;
3592 }
3593}
3594
Bram Moolenaardb913952012-06-29 12:54:53 +02003595 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003596init_range_cmd(exarg_T *eap)
3597{
3598 RangeStart = eap->line1;
3599 RangeEnd = eap->line2;
3600}
3601
3602 static void
3603init_range_eval(typval_T *rettv UNUSED)
3604{
3605 RangeStart = (PyInt) curwin->w_cursor.lnum;
3606 RangeEnd = RangeStart;
3607}
3608
3609 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003610run_cmd(const char *cmd, void *arg UNUSED
3611#ifdef PY_CAN_RECURSE
3612 , PyGILState_STATE *pygilstate UNUSED
3613#endif
3614 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003615{
3616 PyRun_SimpleString((char *) cmd);
3617}
3618
3619static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
3620static int code_hdr_len = 30;
3621
3622 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003623run_do(const char *cmd, void *arg UNUSED
3624#ifdef PY_CAN_RECURSE
3625 , PyGILState_STATE *pygilstate
3626#endif
3627 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003628{
3629 PyInt lnum;
3630 size_t len;
3631 char *code;
3632 int status;
3633 PyObject *pyfunc, *pymain;
3634
Bram Moolenaar4ac66762013-05-28 22:31:46 +02003635 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003636 {
3637 EMSG(_("cannot save undo information"));
3638 return;
3639 }
3640
3641 len = code_hdr_len + STRLEN(cmd);
3642 code = PyMem_New(char, len + 1);
3643 memcpy(code, code_hdr, code_hdr_len);
3644 STRCPY(code + code_hdr_len, cmd);
3645 status = PyRun_SimpleString(code);
3646 PyMem_Free(code);
3647
3648 if (status)
3649 {
3650 EMSG(_("failed to run the code"));
3651 return;
3652 }
3653
3654 status = 0;
3655 pymain = PyImport_AddModule("__main__");
3656 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003657#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003658 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003659#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003660
3661 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
3662 {
3663 PyObject *line, *linenr, *ret;
3664
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003665#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003666 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003667#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003668 if (!(line = GetBufferLine(curbuf, lnum)))
3669 goto err;
3670 if (!(linenr = PyInt_FromLong((long) lnum)))
3671 {
3672 Py_DECREF(line);
3673 goto err;
3674 }
3675 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
3676 Py_DECREF(line);
3677 Py_DECREF(linenr);
3678 if (!ret)
3679 goto err;
3680
3681 if (ret != Py_None)
3682 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
3683 goto err;
3684
3685 Py_XDECREF(ret);
3686 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003687#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003688 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003689#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003690 }
3691 goto out;
3692err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003693#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003694 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003695#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003696 PyErr_PrintEx(0);
3697 PythonIO_Flush();
3698 status = 1;
3699out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003700#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003701 if (!status)
3702 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003703#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003704 Py_DECREF(pyfunc);
3705 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
3706 if (status)
3707 return;
3708 check_cursor();
3709 update_curbuf(NOT_VALID);
3710}
3711
3712 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003713run_eval(const char *cmd, typval_T *rettv
3714#ifdef PY_CAN_RECURSE
3715 , PyGILState_STATE *pygilstate UNUSED
3716#endif
3717 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003718{
3719 PyObject *r;
3720
3721 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
3722 if (r == NULL)
3723 {
3724 if (PyErr_Occurred() && !msg_silent)
3725 PyErr_PrintEx(0);
3726 EMSG(_("E858: Eval did not return a valid python object"));
3727 }
3728 else
3729 {
3730 if (ConvertFromPyObject(r, rettv) == -1)
3731 EMSG(_("E859: Failed to convert returned python object to vim value"));
3732 Py_DECREF(r);
3733 }
3734 PyErr_Clear();
3735}
3736
3737 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02003738set_ref_in_py(const int copyID)
3739{
3740 pylinkedlist_T *cur;
3741 dict_T *dd;
3742 list_T *ll;
3743
3744 if (lastdict != NULL)
3745 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3746 {
3747 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3748 if (dd->dv_copyID != copyID)
3749 {
3750 dd->dv_copyID = copyID;
3751 set_ref_in_ht(&dd->dv_hashtab, copyID);
3752 }
3753 }
3754
3755 if (lastlist != NULL)
3756 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3757 {
3758 ll = ((ListObject *) (cur->pll_obj))->list;
3759 if (ll->lv_copyID != copyID)
3760 {
3761 ll->lv_copyID = copyID;
3762 set_ref_in_list(ll, copyID);
3763 }
3764 }
3765}
3766
3767 static int
3768set_string_copy(char_u *str, typval_T *tv)
3769{
3770 tv->vval.v_string = vim_strsave(str);
3771 if (tv->vval.v_string == NULL)
3772 {
3773 PyErr_NoMemory();
3774 return -1;
3775 }
3776 return 0;
3777}
3778
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003779 static int
3780pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3781{
3782 dict_T *d;
3783 char_u *key;
3784 dictitem_T *di;
3785 PyObject *keyObject;
3786 PyObject *valObject;
3787 Py_ssize_t iter = 0;
3788
3789 d = dict_alloc();
3790 if (d == NULL)
3791 {
3792 PyErr_NoMemory();
3793 return -1;
3794 }
3795
3796 tv->v_type = VAR_DICT;
3797 tv->vval.v_dict = d;
3798
3799 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
3800 {
3801 DICTKEY_DECL
3802
3803 if (keyObject == NULL)
3804 return -1;
3805 if (valObject == NULL)
3806 return -1;
3807
3808 DICTKEY_GET_NOTEMPTY(-1)
3809
3810 di = dictitem_alloc(key);
3811
3812 DICTKEY_UNREF
3813
3814 if (di == NULL)
3815 {
3816 PyErr_NoMemory();
3817 return -1;
3818 }
3819 di->di_tv.v_lock = 0;
3820
3821 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3822 {
3823 vim_free(di);
3824 return -1;
3825 }
3826 if (dict_add(d, di) == FAIL)
3827 {
3828 vim_free(di);
3829 PyErr_SetVim(_("failed to add key to dictionary"));
3830 return -1;
3831 }
3832 }
3833 return 0;
3834}
3835
3836 static int
3837pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3838{
3839 dict_T *d;
3840 char_u *key;
3841 dictitem_T *di;
3842 PyObject *list;
3843 PyObject *litem;
3844 PyObject *keyObject;
3845 PyObject *valObject;
3846 Py_ssize_t lsize;
3847
3848 d = dict_alloc();
3849 if (d == NULL)
3850 {
3851 PyErr_NoMemory();
3852 return -1;
3853 }
3854
3855 tv->v_type = VAR_DICT;
3856 tv->vval.v_dict = d;
3857
3858 list = PyMapping_Items(obj);
3859 if (list == NULL)
3860 return -1;
3861 lsize = PyList_Size(list);
3862 while (lsize--)
3863 {
3864 DICTKEY_DECL
3865
3866 litem = PyList_GetItem(list, lsize);
3867 if (litem == NULL)
3868 {
3869 Py_DECREF(list);
3870 return -1;
3871 }
3872
3873 keyObject = PyTuple_GetItem(litem, 0);
3874 if (keyObject == NULL)
3875 {
3876 Py_DECREF(list);
3877 Py_DECREF(litem);
3878 return -1;
3879 }
3880
3881 DICTKEY_GET_NOTEMPTY(-1)
3882
3883 valObject = PyTuple_GetItem(litem, 1);
3884 if (valObject == NULL)
3885 {
3886 Py_DECREF(list);
3887 Py_DECREF(litem);
3888 return -1;
3889 }
3890
3891 di = dictitem_alloc(key);
3892
3893 DICTKEY_UNREF
3894
3895 if (di == NULL)
3896 {
3897 Py_DECREF(list);
3898 Py_DECREF(litem);
3899 PyErr_NoMemory();
3900 return -1;
3901 }
3902 di->di_tv.v_lock = 0;
3903
3904 if (_ConvertFromPyObject(valObject, &di->di_tv, lookupDict) == -1)
3905 {
3906 vim_free(di);
3907 Py_DECREF(list);
3908 Py_DECREF(litem);
3909 return -1;
3910 }
3911 if (dict_add(d, di) == FAIL)
3912 {
3913 vim_free(di);
3914 Py_DECREF(list);
3915 Py_DECREF(litem);
3916 PyErr_SetVim(_("failed to add key to dictionary"));
3917 return -1;
3918 }
3919 Py_DECREF(litem);
3920 }
3921 Py_DECREF(list);
3922 return 0;
3923}
3924
3925 static int
3926pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3927{
3928 list_T *l;
3929
3930 l = list_alloc();
3931 if (l == NULL)
3932 {
3933 PyErr_NoMemory();
3934 return -1;
3935 }
3936
3937 tv->v_type = VAR_LIST;
3938 tv->vval.v_list = l;
3939
3940 if (list_py_concat(l, obj, lookupDict) == -1)
3941 return -1;
3942
3943 return 0;
3944}
3945
3946 static int
3947pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookupDict)
3948{
3949 PyObject *iterator = PyObject_GetIter(obj);
3950 PyObject *item;
3951 list_T *l;
3952 listitem_T *li;
3953
3954 l = list_alloc();
3955
3956 if (l == NULL)
3957 {
3958 PyErr_NoMemory();
3959 return -1;
3960 }
3961
3962 tv->vval.v_list = l;
3963 tv->v_type = VAR_LIST;
3964
3965
3966 if (iterator == NULL)
3967 return -1;
3968
3969 while ((item = PyIter_Next(obj)))
3970 {
3971 li = listitem_alloc();
3972 if (li == NULL)
3973 {
3974 PyErr_NoMemory();
3975 return -1;
3976 }
3977 li->li_tv.v_lock = 0;
3978
3979 if (_ConvertFromPyObject(item, &li->li_tv, lookupDict) == -1)
3980 return -1;
3981
3982 list_append(l, li);
3983
3984 Py_DECREF(item);
3985 }
3986
3987 Py_DECREF(iterator);
3988 return 0;
3989}
3990
Bram Moolenaardb913952012-06-29 12:54:53 +02003991typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
3992
3993 static int
3994convert_dl(PyObject *obj, typval_T *tv,
3995 pytotvfunc py_to_tv, PyObject *lookupDict)
3996{
3997 PyObject *capsule;
3998 char hexBuf[sizeof(void *) * 2 + 3];
3999
4000 sprintf(hexBuf, "%p", obj);
4001
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004002# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004003 capsule = PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004004# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004005 capsule = (PyObject *)PyDict_GetItemString(lookupDict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004006# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02004007 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02004008 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004009# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004010 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02004011# else
4012 capsule = PyCObject_FromVoidPtr(tv, NULL);
4013# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004014 PyDict_SetItemString(lookupDict, hexBuf, capsule);
4015 Py_DECREF(capsule);
4016 if (py_to_tv(obj, tv, lookupDict) == -1)
4017 {
4018 tv->v_type = VAR_UNKNOWN;
4019 return -1;
4020 }
4021 /* As we are not using copy_tv which increments reference count we must
4022 * do it ourself. */
4023 switch(tv->v_type)
4024 {
4025 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
4026 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
4027 }
4028 }
4029 else
4030 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004031 typval_T *v;
4032
4033# ifdef PY_USE_CAPSULE
4034 v = PyCapsule_GetPointer(capsule, NULL);
4035# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004036 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004037# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004038 copy_tv(v, tv);
4039 }
4040 return 0;
4041}
4042
4043 static int
4044ConvertFromPyObject(PyObject *obj, typval_T *tv)
4045{
4046 PyObject *lookup_dict;
4047 int r;
4048
4049 lookup_dict = PyDict_New();
4050 r = _ConvertFromPyObject(obj, tv, lookup_dict);
4051 Py_DECREF(lookup_dict);
4052 return r;
4053}
4054
4055 static int
4056_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookupDict)
4057{
4058 if (obj->ob_type == &DictionaryType)
4059 {
4060 tv->v_type = VAR_DICT;
4061 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4062 ++tv->vval.v_dict->dv_refcount;
4063 }
4064 else if (obj->ob_type == &ListType)
4065 {
4066 tv->v_type = VAR_LIST;
4067 tv->vval.v_list = (((ListObject *)(obj))->list);
4068 ++tv->vval.v_list->lv_refcount;
4069 }
4070 else if (obj->ob_type == &FunctionType)
4071 {
4072 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
4073 return -1;
4074
4075 tv->v_type = VAR_FUNC;
4076 func_ref(tv->vval.v_string);
4077 }
Bram Moolenaardb913952012-06-29 12:54:53 +02004078 else if (PyBytes_Check(obj))
4079 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004080 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02004081
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004082 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
4083 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004084 if (result == NULL)
4085 return -1;
4086
4087 if (set_string_copy(result, tv) == -1)
4088 return -1;
4089
4090 tv->v_type = VAR_STRING;
4091 }
4092 else if (PyUnicode_Check(obj))
4093 {
4094 PyObject *bytes;
4095 char_u *result;
4096
Bram Moolenaardb913952012-06-29 12:54:53 +02004097 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
4098 if (bytes == NULL)
4099 return -1;
4100
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004101 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
4102 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004103 if (result == NULL)
4104 return -1;
4105
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004106 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02004107 {
4108 Py_XDECREF(bytes);
4109 return -1;
4110 }
4111 Py_XDECREF(bytes);
4112
4113 tv->v_type = VAR_STRING;
4114 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02004115#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02004116 else if (PyInt_Check(obj))
4117 {
4118 tv->v_type = VAR_NUMBER;
4119 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
4120 }
4121#endif
4122 else if (PyLong_Check(obj))
4123 {
4124 tv->v_type = VAR_NUMBER;
4125 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
4126 }
4127 else if (PyDict_Check(obj))
4128 return convert_dl(obj, tv, pydict_to_tv, lookupDict);
4129#ifdef FEAT_FLOAT
4130 else if (PyFloat_Check(obj))
4131 {
4132 tv->v_type = VAR_FLOAT;
4133 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
4134 }
4135#endif
4136 else if (PyIter_Check(obj))
4137 return convert_dl(obj, tv, pyiter_to_tv, lookupDict);
4138 else if (PySequence_Check(obj))
4139 return convert_dl(obj, tv, pyseq_to_tv, lookupDict);
4140 else if (PyMapping_Check(obj))
4141 return convert_dl(obj, tv, pymap_to_tv, lookupDict);
4142 else
4143 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004144 PyErr_SetString(PyExc_TypeError,
4145 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02004146 return -1;
4147 }
4148 return 0;
4149}
4150
4151 static PyObject *
4152ConvertToPyObject(typval_T *tv)
4153{
4154 if (tv == NULL)
4155 {
4156 PyErr_SetVim(_("NULL reference passed"));
4157 return NULL;
4158 }
4159 switch (tv->v_type)
4160 {
4161 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004162 return PyBytes_FromString(tv->vval.v_string == NULL
4163 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004164 case VAR_NUMBER:
4165 return PyLong_FromLong((long) tv->vval.v_number);
4166#ifdef FEAT_FLOAT
4167 case VAR_FLOAT:
4168 return PyFloat_FromDouble((double) tv->vval.v_float);
4169#endif
4170 case VAR_LIST:
4171 return ListNew(tv->vval.v_list);
4172 case VAR_DICT:
4173 return DictionaryNew(tv->vval.v_dict);
4174 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004175 return FunctionNew(tv->vval.v_string == NULL
4176 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004177 case VAR_UNKNOWN:
4178 Py_INCREF(Py_None);
4179 return Py_None;
4180 default:
4181 PyErr_SetVim(_("internal error: invalid value type"));
4182 return NULL;
4183 }
4184}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004185
4186typedef struct
4187{
4188 PyObject_HEAD
4189} CurrentObject;
4190static PyTypeObject CurrentType;
4191
4192 static void
4193init_structs(void)
4194{
4195 vim_memset(&OutputType, 0, sizeof(OutputType));
4196 OutputType.tp_name = "vim.message";
4197 OutputType.tp_basicsize = sizeof(OutputObject);
4198 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
4199 OutputType.tp_doc = "vim message object";
4200 OutputType.tp_methods = OutputMethods;
4201#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004202 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
4203 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004204 OutputType.tp_alloc = call_PyType_GenericAlloc;
4205 OutputType.tp_new = call_PyType_GenericNew;
4206 OutputType.tp_free = call_PyObject_Free;
4207#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004208 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
4209 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004210#endif
4211
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004212 vim_memset(&IterType, 0, sizeof(IterType));
4213 IterType.tp_name = "vim.iter";
4214 IterType.tp_basicsize = sizeof(IterObject);
4215 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
4216 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004217 IterType.tp_iter = (getiterfunc)IterIter;
4218 IterType.tp_iternext = (iternextfunc)IterNext;
4219 IterType.tp_dealloc = (destructor)IterDestructor;
4220 IterType.tp_traverse = (traverseproc)IterTraverse;
4221 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004222
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004223 vim_memset(&BufferType, 0, sizeof(BufferType));
4224 BufferType.tp_name = "vim.buffer";
4225 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004226 BufferType.tp_dealloc = (destructor)BufferDestructor;
4227 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004228 BufferType.tp_as_sequence = &BufferAsSeq;
4229 BufferType.tp_as_mapping = &BufferAsMapping;
4230 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
4231 BufferType.tp_doc = "vim buffer object";
4232 BufferType.tp_methods = BufferMethods;
4233#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004234 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004235 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004236 BufferType.tp_alloc = call_PyType_GenericAlloc;
4237 BufferType.tp_new = call_PyType_GenericNew;
4238 BufferType.tp_free = call_PyObject_Free;
4239#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004240 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004241 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004242#endif
4243
4244 vim_memset(&WindowType, 0, sizeof(WindowType));
4245 WindowType.tp_name = "vim.window";
4246 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004247 WindowType.tp_dealloc = (destructor)WindowDestructor;
4248 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004249 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
4250 WindowType.tp_doc = "vim Window object";
4251 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004252 WindowType.tp_traverse = (traverseproc)WindowTraverse;
4253 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004254#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004255 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
4256 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004257 WindowType.tp_alloc = call_PyType_GenericAlloc;
4258 WindowType.tp_new = call_PyType_GenericNew;
4259 WindowType.tp_free = call_PyObject_Free;
4260#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004261 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
4262 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004263#endif
4264
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004265 vim_memset(&TabPageType, 0, sizeof(TabPageType));
4266 TabPageType.tp_name = "vim.tabpage";
4267 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004268 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
4269 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004270 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
4271 TabPageType.tp_doc = "vim tab page object";
4272 TabPageType.tp_methods = TabPageMethods;
4273#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004274 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004275 TabPageType.tp_alloc = call_PyType_GenericAlloc;
4276 TabPageType.tp_new = call_PyType_GenericNew;
4277 TabPageType.tp_free = call_PyObject_Free;
4278#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004279 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004280#endif
4281
Bram Moolenaardfa38d42013-05-15 13:38:47 +02004282 vim_memset(&BufMapType, 0, sizeof(BufMapType));
4283 BufMapType.tp_name = "vim.bufferlist";
4284 BufMapType.tp_basicsize = sizeof(BufMapObject);
4285 BufMapType.tp_as_mapping = &BufMapAsMapping;
4286 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004287 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004288 BufferType.tp_doc = "vim buffer list";
4289
4290 vim_memset(&WinListType, 0, sizeof(WinListType));
4291 WinListType.tp_name = "vim.windowlist";
4292 WinListType.tp_basicsize = sizeof(WinListType);
4293 WinListType.tp_as_sequence = &WinListAsSeq;
4294 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
4295 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004296 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004297
4298 vim_memset(&TabListType, 0, sizeof(TabListType));
4299 TabListType.tp_name = "vim.tabpagelist";
4300 TabListType.tp_basicsize = sizeof(TabListType);
4301 TabListType.tp_as_sequence = &TabListAsSeq;
4302 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
4303 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004304
4305 vim_memset(&RangeType, 0, sizeof(RangeType));
4306 RangeType.tp_name = "vim.range";
4307 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004308 RangeType.tp_dealloc = (destructor)RangeDestructor;
4309 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004310 RangeType.tp_as_sequence = &RangeAsSeq;
4311 RangeType.tp_as_mapping = &RangeAsMapping;
4312 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
4313 RangeType.tp_doc = "vim Range object";
4314 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004315 RangeType.tp_traverse = (traverseproc)RangeTraverse;
4316 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004317#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004318 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004319 RangeType.tp_alloc = call_PyType_GenericAlloc;
4320 RangeType.tp_new = call_PyType_GenericNew;
4321 RangeType.tp_free = call_PyObject_Free;
4322#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004323 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004324#endif
4325
4326 vim_memset(&CurrentType, 0, sizeof(CurrentType));
4327 CurrentType.tp_name = "vim.currentdata";
4328 CurrentType.tp_basicsize = sizeof(CurrentObject);
4329 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
4330 CurrentType.tp_doc = "vim current object";
4331#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004332 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
4333 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004334#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004335 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
4336 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004337#endif
4338
4339 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
4340 DictionaryType.tp_name = "vim.dictionary";
4341 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004342 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004343 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
4344 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
4345 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
4346 DictionaryType.tp_methods = DictionaryMethods;
4347#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004348 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
4349 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004350#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004351 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
4352 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004353#endif
4354
4355 vim_memset(&ListType, 0, sizeof(ListType));
4356 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004357 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004358 ListType.tp_basicsize = sizeof(ListObject);
4359 ListType.tp_as_sequence = &ListAsSeq;
4360 ListType.tp_as_mapping = &ListAsMapping;
4361 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
4362 ListType.tp_doc = "list pushing modifications to vim structure";
4363 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004364 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004365#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004366 ListType.tp_getattro = (getattrofunc)ListGetattro;
4367 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004368#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004369 ListType.tp_getattr = (getattrfunc)ListGetattr;
4370 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004371#endif
4372
4373 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004374 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004375 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004376 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
4377 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004378 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
4379 FunctionType.tp_doc = "object that calls vim function";
4380 FunctionType.tp_methods = FunctionMethods;
4381#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004382 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004383#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004384 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004385#endif
4386
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004387 vim_memset(&OptionsType, 0, sizeof(OptionsType));
4388 OptionsType.tp_name = "vim.options";
4389 OptionsType.tp_basicsize = sizeof(OptionsObject);
4390 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
4391 OptionsType.tp_doc = "object for manipulating options";
4392 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004393 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
4394 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
4395 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004396
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004397#if PY_MAJOR_VERSION >= 3
4398 vim_memset(&vimmodule, 0, sizeof(vimmodule));
4399 vimmodule.m_name = "vim";
4400 vimmodule.m_doc = "Vim Python interface\n";
4401 vimmodule.m_size = -1;
4402 vimmodule.m_methods = VimMethods;
4403#endif
4404}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004405
4406#define PYTYPE_READY(type) \
4407 if (PyType_Ready(&type)) \
4408 return -1;
4409
4410 static int
4411init_types()
4412{
4413 PYTYPE_READY(IterType);
4414 PYTYPE_READY(BufferType);
4415 PYTYPE_READY(RangeType);
4416 PYTYPE_READY(WindowType);
4417 PYTYPE_READY(TabPageType);
4418 PYTYPE_READY(BufMapType);
4419 PYTYPE_READY(WinListType);
4420 PYTYPE_READY(TabListType);
4421 PYTYPE_READY(CurrentType);
4422 PYTYPE_READY(DictionaryType);
4423 PYTYPE_READY(ListType);
4424 PYTYPE_READY(FunctionType);
4425 PYTYPE_READY(OptionsType);
4426 PYTYPE_READY(OutputType);
4427 return 0;
4428}
4429
4430static BufMapObject TheBufferMap =
4431{
4432 PyObject_HEAD_INIT(&BufMapType)
4433};
4434
4435static WinListObject TheWindowList =
4436{
4437 PyObject_HEAD_INIT(&WinListType)
4438 NULL
4439};
4440
4441static CurrentObject TheCurrent =
4442{
4443 PyObject_HEAD_INIT(&CurrentType)
4444};
4445
4446static TabListObject TheTabPageList =
4447{
4448 PyObject_HEAD_INIT(&TabListType)
4449};
4450
4451static struct numeric_constant {
4452 char *name;
4453 int value;
4454} numeric_constants[] = {
4455 {"VAR_LOCKED", VAR_LOCKED},
4456 {"VAR_FIXED", VAR_FIXED},
4457 {"VAR_SCOPE", VAR_SCOPE},
4458 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
4459};
4460
4461static struct object_constant {
4462 char *name;
4463 PyObject *value;
4464} object_constants[] = {
4465 {"buffers", (PyObject *)(void *)&TheBufferMap},
4466 {"windows", (PyObject *)(void *)&TheWindowList},
4467 {"tabpages", (PyObject *)(void *)&TheTabPageList},
4468 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02004469
4470 {"Buffer", (PyObject *)&BufferType},
4471 {"Range", (PyObject *)&RangeType},
4472 {"Window", (PyObject *)&WindowType},
4473 {"TabPage", (PyObject *)&TabPageType},
4474 {"Dictionary", (PyObject *)&DictionaryType},
4475 {"List", (PyObject *)&ListType},
4476 {"Function", (PyObject *)&FunctionType},
4477 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004478};
4479
4480typedef int (*object_adder)(PyObject *, const char *, PyObject *);
4481
4482#define ADD_OBJECT(m, name, obj) \
4483 if (add_object(m, name, obj)) \
4484 return -1;
4485
4486#define ADD_CHECKED_OBJECT(m, name, obj) \
4487 { \
4488 PyObject *value = obj; \
4489 if (!value) \
4490 return -1; \
4491 ADD_OBJECT(m, name, value); \
4492 }
4493
4494 static int
4495populate_module(PyObject *m, object_adder add_object)
4496{
4497 int i;
4498
4499 for (i = 0; i < (int)(sizeof(numeric_constants)
4500 / sizeof(struct numeric_constant));
4501 ++i)
4502 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
4503 PyInt_FromLong(numeric_constants[i].value));
4504
4505 for (i = 0; i < (int)(sizeof(object_constants)
4506 / sizeof(struct object_constant));
4507 ++i)
4508 {
4509 PyObject *value;
4510
4511 value = object_constants[i].value;
4512 Py_INCREF(value);
4513 ADD_OBJECT(m, object_constants[i].name, value);
4514 }
4515
4516 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
4517 return -1;
4518 ADD_OBJECT(m, "error", VimError);
4519
4520 ADD_CHECKED_OBJECT(m, "vars", DictionaryNew(&globvardict));
4521 ADD_CHECKED_OBJECT(m, "vvars", DictionaryNew(&vimvardict));
4522 ADD_CHECKED_OBJECT(m, "options",
4523 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
4524 return 0;
4525}