blob: 6907494436644a4a862c6dd636ee44387ba9e66f [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 Moolenaardd8aca62013-05-29 22:36:10 +0200120 static int
121add_string(PyObject *list, char *s)
122{
123 PyObject *string;
124
125 if (!(string = PyString_FromString(s)))
126 return -1;
127 if (PyList_Append(list, string))
128 {
129 Py_DECREF(string);
130 return -1;
131 }
132
133 Py_DECREF(string);
134 return 0;
135}
136
137 static PyObject *
138ObjectDir(PyObject *self, char **attributes)
139{
140 PyMethodDef *method;
141 char **attr;
142 PyObject *r;
143
144 if (!(r = PyList_New(0)))
145 return NULL;
146
147 if (self)
148 for (method = self->ob_type->tp_methods ; method->ml_name != NULL ; ++method)
149 if (add_string(r, (char *) method->ml_name))
150 {
151 Py_DECREF(r);
152 return NULL;
153 }
154
155 for (attr = attributes ; *attr ; ++attr)
156 if (add_string(r, *attr))
157 {
158 Py_DECREF(r);
159 return NULL;
160 }
161
162#if PY_MAJOR_VERSION < 3
163 if (add_string(r, "__members__"))
164 {
165 Py_DECREF(r);
166 return NULL;
167 }
168#endif
169
170 return r;
171}
172
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200173/* Output buffer management
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200174 */
175
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200176/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200177typedef void (*writefn)(char_u *);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200178
179static PyTypeObject OutputType;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200180
181typedef struct
182{
183 PyObject_HEAD
184 long softspace;
185 long error;
186} OutputObject;
187
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200188static char *OutputAttrs[] = {
189 "softspace",
190 NULL
191};
192
193 static PyObject *
194OutputDir(PyObject *self)
195{
196 return ObjectDir(self, OutputAttrs);
197}
198
Bram Moolenaar77045652012-09-21 13:46:06 +0200199 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200200OutputSetattr(OutputObject *self, char *name, PyObject *val)
Bram Moolenaar77045652012-09-21 13:46:06 +0200201{
202 if (val == NULL)
203 {
Bram Moolenaar8661b172013-05-15 15:44:28 +0200204 PyErr_SetString(PyExc_AttributeError,
205 _("can't delete OutputObject attributes"));
Bram Moolenaar77045652012-09-21 13:46:06 +0200206 return -1;
207 }
208
209 if (strcmp(name, "softspace") == 0)
210 {
211 if (!PyInt_Check(val))
212 {
213 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
214 return -1;
215 }
216
Bram Moolenaard6e39182013-05-21 18:30:34 +0200217 self->softspace = PyInt_AsLong(val);
Bram Moolenaar77045652012-09-21 13:46:06 +0200218 return 0;
219 }
220
221 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
222 return -1;
223}
224
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200225/* Buffer IO, we write one whole line at a time. */
226static garray_T io_ga = {0, 0, 1, 80, NULL};
227static writefn old_fn = NULL;
228
229 static void
230PythonIO_Flush(void)
231{
232 if (old_fn != NULL && io_ga.ga_len > 0)
233 {
234 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
235 old_fn((char_u *)io_ga.ga_data);
236 }
237 io_ga.ga_len = 0;
238}
239
240 static void
241writer(writefn fn, char_u *str, PyInt n)
242{
243 char_u *ptr;
244
245 /* Flush when switching output function. */
246 if (fn != old_fn)
247 PythonIO_Flush();
248 old_fn = fn;
249
250 /* Write each NL separated line. Text after the last NL is kept for
251 * writing later. */
252 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
253 {
254 PyInt len = ptr - str;
255
256 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
257 break;
258
259 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
260 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
261 fn((char_u *)io_ga.ga_data);
262 str = ptr + 1;
263 n -= len + 1;
264 io_ga.ga_len = 0;
265 }
266
267 /* Put the remaining text into io_ga for later printing. */
268 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
269 {
270 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
271 io_ga.ga_len += (int)n;
272 }
273}
274
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200275 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200276OutputWrite(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200277{
Bram Moolenaare8cdcef2012-09-12 20:21:43 +0200278 Py_ssize_t len = 0;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200279 char *str = NULL;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200280 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200281
Bram Moolenaar27564802011-09-07 19:30:21 +0200282 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200283 return NULL;
284
285 Py_BEGIN_ALLOW_THREADS
286 Python_Lock_Vim();
287 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
288 Python_Release_Vim();
289 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200290 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200291
292 Py_INCREF(Py_None);
293 return Py_None;
294}
295
296 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200297OutputWritelines(OutputObject *self, PyObject *args)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200298{
299 PyInt n;
300 PyInt i;
301 PyObject *list;
Bram Moolenaard6e39182013-05-21 18:30:34 +0200302 int error = self->error;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200303
304 if (!PyArg_ParseTuple(args, "O", &list))
305 return NULL;
306 Py_INCREF(list);
307
Bram Moolenaardb913952012-06-29 12:54:53 +0200308 if (!PyList_Check(list))
309 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200310 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
311 Py_DECREF(list);
312 return NULL;
313 }
314
315 n = PyList_Size(list);
316
317 for (i = 0; i < n; ++i)
318 {
319 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200320 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200321 PyInt len;
322
Bram Moolenaardb913952012-06-29 12:54:53 +0200323 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len))
324 {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200325 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
326 Py_DECREF(list);
327 return NULL;
328 }
329
330 Py_BEGIN_ALLOW_THREADS
331 Python_Lock_Vim();
332 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
333 Python_Release_Vim();
334 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200335 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200336 }
337
338 Py_DECREF(list);
339 Py_INCREF(Py_None);
340 return Py_None;
341}
342
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100343 static PyObject *
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200344OutputFlush(PyObject *self UNUSED)
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100345{
346 /* do nothing */
347 Py_INCREF(Py_None);
348 return Py_None;
349}
350
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200351/***************/
352
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200353static struct PyMethodDef OutputMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200354 /* name, function, calling, doc */
355 {"write", (PyCFunction)OutputWrite, METH_VARARGS, ""},
356 {"writelines", (PyCFunction)OutputWritelines, METH_VARARGS, ""},
357 {"flush", (PyCFunction)OutputFlush, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200358 {"__dir__", (PyCFunction)OutputDir, METH_NOARGS, ""},
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200359 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200360};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200361
362static OutputObject Output =
363{
364 PyObject_HEAD_INIT(&OutputType)
365 0,
366 0
367};
368
369static OutputObject Error =
370{
371 PyObject_HEAD_INIT(&OutputType)
372 0,
373 1
374};
375
376 static int
377PythonIO_Init_io(void)
378{
379 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
380 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
381
382 if (PyErr_Occurred())
383 {
384 EMSG(_("E264: Python: Error initialising I/O objects"));
385 return -1;
386 }
387
388 return 0;
389}
390
391
392static PyObject *VimError;
393
394/* Check to see whether a Vim error has been reported, or a keyboard
395 * interrupt has been detected.
396 */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200397
398 static void
399VimTryStart(void)
400{
401 ++trylevel;
402}
403
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200404 static int
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200405VimTryEnd(void)
406{
407 --trylevel;
408 if (got_int)
409 {
410 PyErr_SetNone(PyExc_KeyboardInterrupt);
411 return 1;
412 }
413 else if (!did_throw)
414 return 0;
415 else if (PyErr_Occurred())
416 return 1;
417 else
418 {
419 PyErr_SetVim((char *) current_exception->value);
420 discard_current_exception();
421 return 1;
422 }
423}
424
425 static int
426VimCheckInterrupt(void)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200427{
428 if (got_int)
429 {
430 PyErr_SetNone(PyExc_KeyboardInterrupt);
431 return 1;
432 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200433 return 0;
434}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200435
436/* Vim module - Implementation
437 */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200438
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200439 static PyObject *
440VimCommand(PyObject *self UNUSED, PyObject *args)
441{
442 char *cmd;
443 PyObject *result;
444
445 if (!PyArg_ParseTuple(args, "s", &cmd))
446 return NULL;
447
448 PyErr_Clear();
449
450 Py_BEGIN_ALLOW_THREADS
451 Python_Lock_Vim();
452
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200453 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200454 do_cmdline_cmd((char_u *)cmd);
455 update_screen(VALID);
456
457 Python_Release_Vim();
458 Py_END_ALLOW_THREADS
459
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200460 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200461 result = NULL;
462 else
463 result = Py_None;
464
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200465
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200466 Py_XINCREF(result);
467 return result;
468}
469
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200470/*
471 * Function to translate a typval_T into a PyObject; this will recursively
472 * translate lists/dictionaries into their Python equivalents.
473 *
474 * The depth parameter is to avoid infinite recursion, set it to 1 when
475 * you call VimToPython.
476 */
477 static PyObject *
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200478VimToPython(typval_T *our_tv, int depth, PyObject *lookup_dict)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200479{
480 PyObject *result;
481 PyObject *newObj;
Bram Moolenaardb913952012-06-29 12:54:53 +0200482 char ptrBuf[sizeof(void *) * 2 + 3];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200483
484 /* Avoid infinite recursion */
485 if (depth > 100)
486 {
487 Py_INCREF(Py_None);
488 result = Py_None;
489 return result;
490 }
491
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200492 /* Check if we run into a recursive loop. The item must be in lookup_dict
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200493 * then and we can use it again. */
494 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
495 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
496 {
Bram Moolenaardb913952012-06-29 12:54:53 +0200497 sprintf(ptrBuf, "%p",
498 our_tv->v_type == VAR_LIST ? (void *)our_tv->vval.v_list
499 : (void *)our_tv->vval.v_dict);
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200500
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200501 if ((result = PyDict_GetItemString(lookup_dict, ptrBuf)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200502 {
503 Py_INCREF(result);
504 return result;
505 }
506 }
507
508 if (our_tv->v_type == VAR_STRING)
509 {
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200510 result = PyString_FromString(our_tv->vval.v_string == NULL
Bram Moolenaard1f13fd2012-10-05 21:30:07 +0200511 ? "" : (char *)our_tv->vval.v_string);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200512 }
513 else if (our_tv->v_type == VAR_NUMBER)
514 {
515 char buf[NUMBUFLEN];
516
517 /* For backwards compatibility numbers are stored as strings. */
518 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200519 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200520 }
521# ifdef FEAT_FLOAT
522 else if (our_tv->v_type == VAR_FLOAT)
523 {
524 char buf[NUMBUFLEN];
525
526 sprintf(buf, "%f", our_tv->vval.v_float);
Bram Moolenaar432b09c2013-05-29 22:26:18 +0200527 result = PyString_FromString((char *) buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200528 }
529# endif
530 else if (our_tv->v_type == VAR_LIST)
531 {
532 list_T *list = our_tv->vval.v_list;
533 listitem_T *curr;
534
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200535 if (list == NULL)
536 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200537
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200538 if (!(result = PyList_New(0)))
539 return NULL;
540
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200541 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200542 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200543 Py_DECREF(result);
544 return NULL;
545 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200546
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200547 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
548 {
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200549 if (!(newObj = VimToPython(&curr->li_tv, depth + 1, lookup_dict)))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200550 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200551 Py_DECREF(result);
552 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200553 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200554 if (PyList_Append(result, newObj))
555 {
556 Py_DECREF(newObj);
557 Py_DECREF(result);
558 return NULL;
559 }
560 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200561 }
562 }
563 else if (our_tv->v_type == VAR_DICT)
564 {
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200565
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200566 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
567 long_u todo = ht->ht_used;
568 hashitem_T *hi;
569 dictitem_T *di;
570 if (our_tv->vval.v_dict == NULL)
571 return NULL;
572
573 if (!(result = PyDict_New()))
574 return NULL;
575
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200576 if (PyDict_SetItemString(lookup_dict, ptrBuf, result))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200577 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200578 Py_DECREF(result);
579 return NULL;
580 }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200581
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200582 for (hi = ht->ht_array; todo > 0; ++hi)
583 {
584 if (!HASHITEM_EMPTY(hi))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200585 {
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200586 --todo;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200587
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200588 di = dict_lookup(hi);
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200589 if (!(newObj = VimToPython(&di->di_tv, depth + 1, lookup_dict)))
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200590 {
591 Py_DECREF(result);
592 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200593 }
Bram Moolenaar21642ed2013-05-29 22:20:01 +0200594 if (PyDict_SetItemString(result, (char *)hi->hi_key, newObj))
595 {
596 Py_DECREF(result);
597 Py_DECREF(newObj);
598 return NULL;
599 }
600 Py_DECREF(newObj);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200601 }
602 }
603 }
604 else
605 {
606 Py_INCREF(Py_None);
607 result = Py_None;
608 }
609
610 return result;
611}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200612
613 static PyObject *
Bram Moolenaar774267b2013-05-21 20:51:59 +0200614VimEval(PyObject *self UNUSED, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200615{
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200616 char *expr;
617 typval_T *our_tv;
618 PyObject *result;
619 PyObject *lookup_dict;
620
621 if (!PyArg_ParseTuple(args, "s", &expr))
622 return NULL;
623
624 Py_BEGIN_ALLOW_THREADS
625 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200626 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200627 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200628 Python_Release_Vim();
629 Py_END_ALLOW_THREADS
630
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200631 if (VimTryEnd())
632 return NULL;
633
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200634 if (our_tv == NULL)
635 {
636 PyErr_SetVim(_("invalid expression"));
637 return NULL;
638 }
639
640 /* Convert the Vim type into a Python type. Create a dictionary that's
641 * used to check for recursive loops. */
642 lookup_dict = PyDict_New();
643 result = VimToPython(our_tv, 1, lookup_dict);
644 Py_DECREF(lookup_dict);
645
646
647 Py_BEGIN_ALLOW_THREADS
648 Python_Lock_Vim();
649 free_tv(our_tv);
650 Python_Release_Vim();
651 Py_END_ALLOW_THREADS
652
653 return result;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200654}
655
Bram Moolenaardb913952012-06-29 12:54:53 +0200656static PyObject *ConvertToPyObject(typval_T *);
657
658 static PyObject *
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200659VimEvalPy(PyObject *self UNUSED, PyObject *args)
Bram Moolenaardb913952012-06-29 12:54:53 +0200660{
Bram Moolenaardb913952012-06-29 12:54:53 +0200661 char *expr;
662 typval_T *our_tv;
663 PyObject *result;
664
665 if (!PyArg_ParseTuple(args, "s", &expr))
666 return NULL;
667
668 Py_BEGIN_ALLOW_THREADS
669 Python_Lock_Vim();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200670 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +0200671 our_tv = eval_expr((char_u *)expr, NULL);
Bram Moolenaardb913952012-06-29 12:54:53 +0200672 Python_Release_Vim();
673 Py_END_ALLOW_THREADS
674
Bram Moolenaara7b64ce2013-05-21 20:40:40 +0200675 if (VimTryEnd())
676 return NULL;
677
Bram Moolenaardb913952012-06-29 12:54:53 +0200678 if (our_tv == NULL)
679 {
680 PyErr_SetVim(_("invalid expression"));
681 return NULL;
682 }
683
684 result = ConvertToPyObject(our_tv);
685 Py_BEGIN_ALLOW_THREADS
686 Python_Lock_Vim();
687 free_tv(our_tv);
688 Python_Release_Vim();
689 Py_END_ALLOW_THREADS
690
691 return result;
Bram Moolenaardb913952012-06-29 12:54:53 +0200692}
693
694 static PyObject *
695VimStrwidth(PyObject *self UNUSED, PyObject *args)
696{
697 char *expr;
698
699 if (!PyArg_ParseTuple(args, "s", &expr))
700 return NULL;
701
Bram Moolenaara54bf402012-12-05 16:30:07 +0100702 return PyLong_FromLong(
703#ifdef FEAT_MBYTE
704 mb_string2cells((char_u *)expr, (int)STRLEN(expr))
705#else
706 STRLEN(expr)
707#endif
708 );
Bram Moolenaardb913952012-06-29 12:54:53 +0200709}
710
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200711/*
712 * Vim module - Definitions
713 */
714
715static struct PyMethodDef VimMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +0200716 /* name, function, calling, documentation */
717 {"command", VimCommand, METH_VARARGS, "Execute a Vim ex-mode command" },
718 {"eval", VimEval, METH_VARARGS, "Evaluate an expression using Vim evaluator" },
719 {"bindeval", VimEvalPy, METH_VARARGS, "Like eval(), but returns objects attached to vim ones"},
720 {"strwidth", VimStrwidth, METH_VARARGS, "Screen string width, counts <Tab> as having width 1"},
721 { NULL, NULL, 0, NULL }
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200722};
723
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200724/*
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200725 * Generic iterator object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200726 */
727
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200728static PyTypeObject IterType;
729
730typedef PyObject *(*nextfun)(void **);
731typedef void (*destructorfun)(void *);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200732typedef int (*traversefun)(void *, visitproc, void *);
733typedef int (*clearfun)(void **);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200734
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200735/* Main purpose of this object is removing the need for do python
736 * initialization (i.e. PyType_Ready and setting type attributes) for a big
737 * bunch of objects. */
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +0200738
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200739typedef struct
740{
741 PyObject_HEAD
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200742 void *cur;
743 nextfun next;
744 destructorfun destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200745 traversefun traverse;
746 clearfun clear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200747} IterObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200748
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200749 static PyObject *
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200750IterNew(void *start, destructorfun destruct, nextfun next, traversefun traverse,
751 clearfun clear)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200752{
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200753 IterObject *self;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200754
Bram Moolenaar774267b2013-05-21 20:51:59 +0200755 self = PyObject_GC_New(IterObject, &IterType);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200756 self->cur = start;
757 self->next = next;
758 self->destruct = destruct;
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200759 self->traverse = traverse;
760 self->clear = clear;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200761
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200762 return (PyObject *)(self);
763}
764
765 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200766IterDestructor(IterObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200767{
Bram Moolenaar774267b2013-05-21 20:51:59 +0200768 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +0200769 self->destruct(self->cur);
Bram Moolenaar774267b2013-05-21 20:51:59 +0200770 PyObject_GC_Del((void *)(self));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200771}
772
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200773 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200774IterTraverse(IterObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200775{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200776 if (self->traverse != NULL)
777 return self->traverse(self->cur, visit, arg);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200778 else
779 return 0;
780}
781
Bram Moolenaar9e74e302013-05-17 21:20:17 +0200782/* Mac OSX defines clear() somewhere. */
783#ifdef clear
784# undef clear
785#endif
786
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200787 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200788IterClear(IterObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200789{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200790 if (self->clear != NULL)
791 return self->clear(&self->cur);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +0200792 else
793 return 0;
794}
795
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200796 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200797IterNext(IterObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200798{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200799 return self->next(&self->cur);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200800}
801
Bram Moolenaarb6c589a2013-05-15 14:39:52 +0200802 static PyObject *
803IterIter(PyObject *self)
804{
805 return self;
806}
Bram Moolenaardfa38d42013-05-15 13:38:47 +0200807
Bram Moolenaardb913952012-06-29 12:54:53 +0200808typedef struct pylinkedlist_S {
809 struct pylinkedlist_S *pll_next;
810 struct pylinkedlist_S *pll_prev;
811 PyObject *pll_obj;
812} pylinkedlist_T;
813
814static pylinkedlist_T *lastdict = NULL;
815static pylinkedlist_T *lastlist = NULL;
816
817 static void
818pyll_remove(pylinkedlist_T *ref, pylinkedlist_T **last)
819{
820 if (ref->pll_prev == NULL)
821 {
822 if (ref->pll_next == NULL)
823 {
824 *last = NULL;
825 return;
826 }
827 }
828 else
829 ref->pll_prev->pll_next = ref->pll_next;
830
831 if (ref->pll_next == NULL)
832 *last = ref->pll_prev;
833 else
834 ref->pll_next->pll_prev = ref->pll_prev;
835}
836
837 static void
838pyll_add(PyObject *self, pylinkedlist_T *ref, pylinkedlist_T **last)
839{
840 if (*last == NULL)
841 ref->pll_prev = NULL;
842 else
843 {
844 (*last)->pll_next = ref;
845 ref->pll_prev = *last;
846 }
847 ref->pll_next = NULL;
848 ref->pll_obj = self;
849 *last = ref;
850}
851
852static PyTypeObject DictionaryType;
853
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200854#define DICTKEY_GET_NOTEMPTY(err) \
855 DICTKEY_GET(err) \
856 if (*key == NUL) \
857 { \
858 PyErr_SetString(PyExc_ValueError, _("empty keys are not allowed")); \
859 return err; \
860 }
861
Bram Moolenaardb913952012-06-29 12:54:53 +0200862typedef struct
863{
864 PyObject_HEAD
865 dict_T *dict;
866 pylinkedlist_T ref;
867} DictionaryObject;
868
869 static PyObject *
870DictionaryNew(dict_T *dict)
871{
872 DictionaryObject *self;
873
874 self = PyObject_NEW(DictionaryObject, &DictionaryType);
875 if (self == NULL)
876 return NULL;
877 self->dict = dict;
878 ++dict->dv_refcount;
879
880 pyll_add((PyObject *)(self), &self->ref, &lastdict);
881
882 return (PyObject *)(self);
883}
884
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200885 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +0200886DictionaryDestructor(DictionaryObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200887{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200888 pyll_remove(&self->ref, &lastdict);
889 dict_unref(self->dict);
Bram Moolenaar4d1da492013-04-24 13:39:15 +0200890
891 DESTRUCTOR_FINISH(self);
892}
893
Bram Moolenaardd8aca62013-05-29 22:36:10 +0200894static char *DictionaryAttrs[] = {
895 "locked", "scope",
896 NULL
897};
898
899 static PyObject *
900DictionaryDir(PyObject *self)
901{
902 return ObjectDir(self, DictionaryAttrs);
903}
904
Bram Moolenaardb913952012-06-29 12:54:53 +0200905 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +0200906DictionarySetattr(DictionaryObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200907{
908 if (val == NULL)
909 {
910 PyErr_SetString(PyExc_AttributeError, _("Cannot delete DictionaryObject attributes"));
911 return -1;
912 }
913
914 if (strcmp(name, "locked") == 0)
915 {
Bram Moolenaard6e39182013-05-21 18:30:34 +0200916 if (self->dict->dv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +0200917 {
918 PyErr_SetString(PyExc_TypeError, _("Cannot modify fixed dictionary"));
919 return -1;
920 }
921 else
922 {
Bram Moolenaarb983f752013-05-15 16:11:50 +0200923 int istrue = PyObject_IsTrue(val);
924 if (istrue == -1)
925 return -1;
926 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +0200927 self->dict->dv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200928 else
Bram Moolenaard6e39182013-05-21 18:30:34 +0200929 self->dict->dv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +0200930 }
931 return 0;
932 }
933 else
934 {
935 PyErr_SetString(PyExc_AttributeError, _("Cannot set this attribute"));
936 return -1;
937 }
938}
939
940 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200941DictionaryLength(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +0200942{
Bram Moolenaard6e39182013-05-21 18:30:34 +0200943 return ((PyInt) (self->dict->dv_hashtab.ht_used));
Bram Moolenaardb913952012-06-29 12:54:53 +0200944}
945
946 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +0200947DictionaryItem(DictionaryObject *self, PyObject *keyObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200948{
949 char_u *key;
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200950 dictitem_T *di;
Bram Moolenaardb913952012-06-29 12:54:53 +0200951 DICTKEY_DECL
952
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200953 DICTKEY_GET_NOTEMPTY(NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +0200954
Bram Moolenaard6e39182013-05-21 18:30:34 +0200955 di = dict_find(self->dict, key, -1);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200956
Bram Moolenaar696c2112012-09-21 13:43:14 +0200957 DICTKEY_UNREF
958
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200959 if (di == NULL)
960 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200961 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200962 return NULL;
963 }
Bram Moolenaardb913952012-06-29 12:54:53 +0200964
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200965 return ConvertToPyObject(&di->di_tv);
Bram Moolenaardb913952012-06-29 12:54:53 +0200966}
967
968 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +0200969DictionaryAssItem(DictionaryObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaardb913952012-06-29 12:54:53 +0200970{
971 char_u *key;
972 typval_T tv;
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200973 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +0200974 dictitem_T *di;
975 DICTKEY_DECL
976
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200977 if (dict->dv_lock)
Bram Moolenaardb913952012-06-29 12:54:53 +0200978 {
979 PyErr_SetVim(_("dict is locked"));
980 return -1;
981 }
982
Bram Moolenaar231e1a12012-09-05 18:45:28 +0200983 DICTKEY_GET_NOTEMPTY(-1)
Bram Moolenaardb913952012-06-29 12:54:53 +0200984
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200985 di = dict_find(dict, key, -1);
Bram Moolenaardb913952012-06-29 12:54:53 +0200986
987 if (valObject == NULL)
988 {
Bram Moolenaarf27839c2012-06-29 16:19:50 +0200989 hashitem_T *hi;
990
Bram Moolenaardb913952012-06-29 12:54:53 +0200991 if (di == NULL)
992 {
Bram Moolenaar696c2112012-09-21 13:43:14 +0200993 DICTKEY_UNREF
Bram Moolenaar4d188da2013-05-15 15:35:09 +0200994 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaardb913952012-06-29 12:54:53 +0200995 return -1;
996 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +0200997 hi = hash_find(&dict->dv_hashtab, di->di_key);
998 hash_remove(&dict->dv_hashtab, hi);
Bram Moolenaardb913952012-06-29 12:54:53 +0200999 dictitem_free(di);
1000 return 0;
1001 }
1002
1003 if (ConvertFromPyObject(valObject, &tv) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02001004 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02001005
1006 if (di == NULL)
1007 {
1008 di = dictitem_alloc(key);
1009 if (di == NULL)
1010 {
1011 PyErr_NoMemory();
1012 return -1;
1013 }
1014 di->di_tv.v_lock = 0;
1015
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001016 if (dict_add(dict, di) == FAIL)
Bram Moolenaardb913952012-06-29 12:54:53 +02001017 {
Bram Moolenaar696c2112012-09-21 13:43:14 +02001018 DICTKEY_UNREF
Bram Moolenaardb913952012-06-29 12:54:53 +02001019 vim_free(di);
1020 PyErr_SetVim(_("failed to add key to dictionary"));
1021 return -1;
1022 }
1023 }
1024 else
1025 clear_tv(&di->di_tv);
1026
1027 DICTKEY_UNREF
1028
1029 copy_tv(&tv, &di->di_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001030 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001031 return 0;
1032}
1033
1034 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001035DictionaryListKeys(DictionaryObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001036{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001037 dict_T *dict = self->dict;
Bram Moolenaardb913952012-06-29 12:54:53 +02001038 long_u todo = dict->dv_hashtab.ht_used;
1039 Py_ssize_t i = 0;
1040 PyObject *r;
1041 hashitem_T *hi;
1042
1043 r = PyList_New(todo);
1044 for (hi = dict->dv_hashtab.ht_array; todo > 0; ++hi)
1045 {
1046 if (!HASHITEM_EMPTY(hi))
1047 {
1048 PyList_SetItem(r, i, PyBytes_FromString((char *)(hi->hi_key)));
1049 --todo;
1050 ++i;
1051 }
1052 }
1053 return r;
1054}
1055
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02001056static PyMappingMethods DictionaryAsMapping = {
1057 (lenfunc) DictionaryLength,
1058 (binaryfunc) DictionaryItem,
1059 (objobjargproc) DictionaryAssItem,
1060};
1061
Bram Moolenaardb913952012-06-29 12:54:53 +02001062static struct PyMethodDef DictionaryMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02001063 {"keys", (PyCFunction)DictionaryListKeys, METH_NOARGS, ""},
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001064 {"__dir__", (PyCFunction)DictionaryDir, METH_NOARGS, ""},
1065 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001066};
1067
1068static PyTypeObject ListType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001069static PySequenceMethods ListAsSeq;
1070static PyMappingMethods ListAsMapping;
Bram Moolenaardb913952012-06-29 12:54:53 +02001071
1072typedef struct
1073{
1074 PyObject_HEAD
1075 list_T *list;
1076 pylinkedlist_T ref;
1077} ListObject;
1078
1079 static PyObject *
1080ListNew(list_T *list)
1081{
1082 ListObject *self;
1083
1084 self = PyObject_NEW(ListObject, &ListType);
1085 if (self == NULL)
1086 return NULL;
1087 self->list = list;
1088 ++list->lv_refcount;
1089
1090 pyll_add((PyObject *)(self), &self->ref, &lastlist);
1091
1092 return (PyObject *)(self);
1093}
1094
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001095 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001096ListDestructor(ListObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001097{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001098 pyll_remove(&self->ref, &lastlist);
1099 list_unref(self->list);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001100
1101 DESTRUCTOR_FINISH(self);
1102}
1103
Bram Moolenaardb913952012-06-29 12:54:53 +02001104 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001105list_py_concat(list_T *l, PyObject *obj, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02001106{
1107 Py_ssize_t i;
1108 Py_ssize_t lsize = PySequence_Size(obj);
1109 PyObject *litem;
1110 listitem_T *li;
1111
1112 for(i=0; i<lsize; i++)
1113 {
1114 li = listitem_alloc();
1115 if (li == NULL)
1116 {
1117 PyErr_NoMemory();
1118 return -1;
1119 }
1120 li->li_tv.v_lock = 0;
1121
1122 litem = PySequence_GetItem(obj, i);
1123 if (litem == NULL)
1124 return -1;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02001125 if (_ConvertFromPyObject(litem, &li->li_tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02001126 return -1;
1127
1128 list_append(l, li);
1129 }
1130 return 0;
1131}
1132
Bram Moolenaardb913952012-06-29 12:54:53 +02001133 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02001134ListLength(ListObject *self)
Bram Moolenaardb913952012-06-29 12:54:53 +02001135{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001136 return ((PyInt) (self->list->lv_len));
Bram Moolenaardb913952012-06-29 12:54:53 +02001137}
1138
1139 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001140ListItem(ListObject *self, Py_ssize_t index)
Bram Moolenaardb913952012-06-29 12:54:53 +02001141{
1142 listitem_T *li;
1143
Bram Moolenaard6e39182013-05-21 18:30:34 +02001144 if (index >= ListLength(self))
Bram Moolenaardb913952012-06-29 12:54:53 +02001145 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001146 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001147 return NULL;
1148 }
Bram Moolenaard6e39182013-05-21 18:30:34 +02001149 li = list_find(self->list, (long) index);
Bram Moolenaardb913952012-06-29 12:54:53 +02001150 if (li == NULL)
1151 {
1152 PyErr_SetVim(_("internal error: failed to get vim list item"));
1153 return NULL;
1154 }
1155 return ConvertToPyObject(&li->li_tv);
1156}
1157
1158#define PROC_RANGE \
1159 if (last < 0) {\
1160 if (last < -size) \
1161 last = 0; \
1162 else \
1163 last += size; \
1164 } \
1165 if (first < 0) \
1166 first = 0; \
1167 if (first > size) \
1168 first = size; \
1169 if (last > size) \
1170 last = size;
1171
1172 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001173ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
Bram Moolenaardb913952012-06-29 12:54:53 +02001174{
1175 PyInt i;
1176 PyInt size = ListLength(self);
1177 PyInt n;
1178 PyObject *list;
1179 int reversed = 0;
1180
1181 PROC_RANGE
1182 if (first >= last)
1183 first = last;
1184
1185 n = last-first;
1186 list = PyList_New(n);
1187 if (list == NULL)
1188 return NULL;
1189
1190 for (i = 0; i < n; ++i)
1191 {
Bram Moolenaar24b11fb2013-04-05 19:32:36 +02001192 PyObject *item = ListItem(self, first + i);
Bram Moolenaardb913952012-06-29 12:54:53 +02001193 if (item == NULL)
1194 {
1195 Py_DECREF(list);
1196 return NULL;
1197 }
1198
1199 if ((PyList_SetItem(list, ((reversed)?(n-i-1):(i)), item)))
1200 {
1201 Py_DECREF(item);
1202 Py_DECREF(list);
1203 return NULL;
1204 }
1205 }
1206
1207 return list;
1208}
1209
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001210typedef struct
1211{
1212 listwatch_T lw;
1213 list_T *list;
1214} listiterinfo_T;
1215
1216 static void
1217ListIterDestruct(listiterinfo_T *lii)
1218{
1219 list_rem_watch(lii->list, &lii->lw);
1220 PyMem_Free(lii);
1221}
1222
1223 static PyObject *
1224ListIterNext(listiterinfo_T **lii)
1225{
1226 PyObject *r;
1227
1228 if (!((*lii)->lw.lw_item))
1229 return NULL;
1230
1231 if (!(r = ConvertToPyObject(&((*lii)->lw.lw_item->li_tv))))
1232 return NULL;
1233
1234 (*lii)->lw.lw_item = (*lii)->lw.lw_item->li_next;
1235
1236 return r;
1237}
1238
1239 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001240ListIter(ListObject *self)
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001241{
1242 listiterinfo_T *lii;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001243 list_T *l = self->list;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001244
1245 if (!(lii = PyMem_New(listiterinfo_T, 1)))
1246 {
1247 PyErr_NoMemory();
1248 return NULL;
1249 }
1250
1251 list_add_watch(l, &lii->lw);
1252 lii->lw.lw_item = l->lv_first;
1253 lii->list = l;
1254
1255 return IterNew(lii,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001256 (destructorfun) ListIterDestruct, (nextfun) ListIterNext,
1257 NULL, NULL);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02001258}
1259
Bram Moolenaardb913952012-06-29 12:54:53 +02001260 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001261ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001262{
1263 typval_T tv;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001264 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001265 listitem_T *li;
1266 Py_ssize_t length = ListLength(self);
1267
1268 if (l->lv_lock)
1269 {
1270 PyErr_SetVim(_("list is locked"));
1271 return -1;
1272 }
1273 if (index>length || (index==length && obj==NULL))
1274 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001275 PyErr_SetString(PyExc_IndexError, _("list index out of range"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001276 return -1;
1277 }
1278
1279 if (obj == NULL)
1280 {
1281 li = list_find(l, (long) index);
1282 list_remove(l, li, li);
1283 clear_tv(&li->li_tv);
1284 vim_free(li);
1285 return 0;
1286 }
1287
1288 if (ConvertFromPyObject(obj, &tv) == -1)
1289 return -1;
1290
1291 if (index == length)
1292 {
1293 if (list_append_tv(l, &tv) == FAIL)
1294 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001295 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001296 PyErr_SetVim(_("Failed to add item to list"));
1297 return -1;
1298 }
1299 }
1300 else
1301 {
1302 li = list_find(l, (long) index);
1303 clear_tv(&li->li_tv);
1304 copy_tv(&tv, &li->li_tv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001305 clear_tv(&tv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001306 }
1307 return 0;
1308}
1309
1310 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001311ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001312{
1313 PyInt size = ListLength(self);
1314 Py_ssize_t i;
1315 Py_ssize_t lsize;
1316 PyObject *litem;
1317 listitem_T *li;
1318 listitem_T *next;
1319 typval_T v;
Bram Moolenaard6e39182013-05-21 18:30:34 +02001320 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001321
1322 if (l->lv_lock)
1323 {
1324 PyErr_SetVim(_("list is locked"));
1325 return -1;
1326 }
1327
1328 PROC_RANGE
1329
1330 if (first == size)
1331 li = NULL;
1332 else
1333 {
1334 li = list_find(l, (long) first);
1335 if (li == NULL)
1336 {
1337 PyErr_SetVim(_("internal error: no vim list item"));
1338 return -1;
1339 }
1340 if (last > first)
1341 {
1342 i = last - first;
1343 while (i-- && li != NULL)
1344 {
1345 next = li->li_next;
1346 listitem_remove(l, li);
1347 li = next;
1348 }
1349 }
1350 }
1351
1352 if (obj == NULL)
1353 return 0;
1354
1355 if (!PyList_Check(obj))
1356 {
1357 PyErr_SetString(PyExc_TypeError, _("can only assign lists to slice"));
1358 return -1;
1359 }
1360
1361 lsize = PyList_Size(obj);
1362
1363 for(i=0; i<lsize; i++)
1364 {
1365 litem = PyList_GetItem(obj, i);
1366 if (litem == NULL)
1367 return -1;
1368 if (ConvertFromPyObject(litem, &v) == -1)
1369 return -1;
1370 if (list_insert_tv(l, &v, li) == FAIL)
1371 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001372 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001373 PyErr_SetVim(_("internal error: failed to add item to list"));
1374 return -1;
1375 }
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001376 clear_tv(&v);
Bram Moolenaardb913952012-06-29 12:54:53 +02001377 }
1378 return 0;
1379}
1380
1381 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001382ListConcatInPlace(ListObject *self, PyObject *obj)
Bram Moolenaardb913952012-06-29 12:54:53 +02001383{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001384 list_T *l = self->list;
Bram Moolenaardb913952012-06-29 12:54:53 +02001385 PyObject *lookup_dict;
1386
1387 if (l->lv_lock)
1388 {
1389 PyErr_SetVim(_("list is locked"));
1390 return NULL;
1391 }
1392
1393 if (!PySequence_Check(obj))
1394 {
1395 PyErr_SetString(PyExc_TypeError, _("can only concatenate with lists"));
1396 return NULL;
1397 }
1398
1399 lookup_dict = PyDict_New();
1400 if (list_py_concat(l, obj, lookup_dict) == -1)
1401 {
1402 Py_DECREF(lookup_dict);
1403 return NULL;
1404 }
1405 Py_DECREF(lookup_dict);
1406
1407 Py_INCREF(self);
Bram Moolenaard6e39182013-05-21 18:30:34 +02001408 return (PyObject *)(self);
Bram Moolenaardb913952012-06-29 12:54:53 +02001409}
1410
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001411static char *ListAttrs[] = {
1412 "locked",
1413 NULL
1414};
1415
1416 static PyObject *
1417ListDir(PyObject *self)
1418{
1419 return ObjectDir(self, ListAttrs);
1420}
1421
Bram Moolenaar66b79852012-09-21 14:00:35 +02001422 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001423ListSetattr(ListObject *self, char *name, PyObject *val)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001424{
1425 if (val == NULL)
1426 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001427 PyErr_SetString(PyExc_AttributeError,
1428 _("cannot delete vim.dictionary attributes"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001429 return -1;
1430 }
1431
1432 if (strcmp(name, "locked") == 0)
1433 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001434 if (self->list->lv_lock == VAR_FIXED)
Bram Moolenaar66b79852012-09-21 14:00:35 +02001435 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001436 PyErr_SetString(PyExc_TypeError, _("cannot modify fixed list"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001437 return -1;
1438 }
1439 else
1440 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001441 int istrue = PyObject_IsTrue(val);
1442 if (istrue == -1)
1443 return -1;
1444 else if (istrue)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001445 self->list->lv_lock = VAR_LOCKED;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001446 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001447 self->list->lv_lock = 0;
Bram Moolenaar66b79852012-09-21 14:00:35 +02001448 }
1449 return 0;
1450 }
1451 else
1452 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001453 PyErr_SetString(PyExc_AttributeError, _("cannot set this attribute"));
Bram Moolenaar66b79852012-09-21 14:00:35 +02001454 return -1;
1455 }
1456}
1457
Bram Moolenaardb913952012-06-29 12:54:53 +02001458static struct PyMethodDef ListMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001459 {"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
1460 {"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
1461 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001462};
1463
1464typedef struct
1465{
1466 PyObject_HEAD
1467 char_u *name;
1468} FunctionObject;
1469
1470static PyTypeObject FunctionType;
1471
1472 static PyObject *
1473FunctionNew(char_u *name)
1474{
1475 FunctionObject *self;
1476
1477 self = PyObject_NEW(FunctionObject, &FunctionType);
1478 if (self == NULL)
1479 return NULL;
1480 self->name = PyMem_New(char_u, STRLEN(name) + 1);
1481 if (self->name == NULL)
1482 {
1483 PyErr_NoMemory();
1484 return NULL;
1485 }
1486 STRCPY(self->name, name);
1487 func_ref(name);
1488 return (PyObject *)(self);
1489}
1490
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001491 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001492FunctionDestructor(FunctionObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001493{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001494 func_unref(self->name);
1495 PyMem_Free(self->name);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02001496
1497 DESTRUCTOR_FINISH(self);
1498}
1499
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001500static char *FunctionAttrs[] = {
1501 "softspace",
1502 NULL
1503};
1504
1505 static PyObject *
1506FunctionDir(PyObject *self)
1507{
1508 return ObjectDir(self, FunctionAttrs);
1509}
1510
Bram Moolenaardb913952012-06-29 12:54:53 +02001511 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001512FunctionCall(FunctionObject *self, PyObject *argsObject, PyObject *kwargs)
Bram Moolenaardb913952012-06-29 12:54:53 +02001513{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001514 char_u *name = self->name;
Bram Moolenaardb913952012-06-29 12:54:53 +02001515 typval_T args;
1516 typval_T selfdicttv;
1517 typval_T rettv;
1518 dict_T *selfdict = NULL;
1519 PyObject *selfdictObject;
1520 PyObject *result;
1521 int error;
1522
1523 if (ConvertFromPyObject(argsObject, &args) == -1)
1524 return NULL;
1525
1526 if (kwargs != NULL)
1527 {
1528 selfdictObject = PyDict_GetItemString(kwargs, "self");
1529 if (selfdictObject != NULL)
1530 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001531 if (!PyMapping_Check(selfdictObject))
Bram Moolenaardb913952012-06-29 12:54:53 +02001532 {
Bram Moolenaar9581b5f2012-07-25 15:36:04 +02001533 PyErr_SetString(PyExc_TypeError,
1534 _("'self' argument must be a dictionary"));
Bram Moolenaardb913952012-06-29 12:54:53 +02001535 clear_tv(&args);
1536 return NULL;
1537 }
1538 if (ConvertFromPyObject(selfdictObject, &selfdicttv) == -1)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001539 {
1540 clear_tv(&args);
Bram Moolenaardb913952012-06-29 12:54:53 +02001541 return NULL;
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001542 }
Bram Moolenaardb913952012-06-29 12:54:53 +02001543 selfdict = selfdicttv.vval.v_dict;
1544 }
1545 }
1546
Bram Moolenaar71700b82013-05-15 17:49:05 +02001547 Py_BEGIN_ALLOW_THREADS
1548 Python_Lock_Vim();
1549
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001550 VimTryStart();
Bram Moolenaardb913952012-06-29 12:54:53 +02001551 error = func_call(name, &args, selfdict, &rettv);
Bram Moolenaar71700b82013-05-15 17:49:05 +02001552
1553 Python_Release_Vim();
1554 Py_END_ALLOW_THREADS
1555
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001556 if (VimTryEnd())
1557 result = NULL;
1558 else if (error != OK)
Bram Moolenaardb913952012-06-29 12:54:53 +02001559 {
1560 result = NULL;
1561 PyErr_SetVim(_("failed to run function"));
1562 }
1563 else
1564 result = ConvertToPyObject(&rettv);
1565
Bram Moolenaardb913952012-06-29 12:54:53 +02001566 clear_tv(&args);
1567 clear_tv(&rettv);
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001568 if (selfdict != NULL)
1569 clear_tv(&selfdicttv);
Bram Moolenaardb913952012-06-29 12:54:53 +02001570
1571 return result;
1572}
1573
1574static struct PyMethodDef FunctionMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001575 {"__call__",(PyCFunction)FunctionCall, METH_VARARGS|METH_KEYWORDS, ""},
1576 {"__dir__", (PyCFunction)FunctionDir, METH_NOARGS, ""},
1577 { NULL, NULL, 0, NULL}
Bram Moolenaardb913952012-06-29 12:54:53 +02001578};
1579
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001580/*
1581 * Options object
1582 */
1583
1584static PyTypeObject OptionsType;
1585
1586typedef int (*checkfun)(void *);
1587
1588typedef struct
1589{
1590 PyObject_HEAD
1591 int opt_type;
1592 void *from;
1593 checkfun Check;
1594 PyObject *fromObj;
1595} OptionsObject;
1596
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001597 static int
1598dummy_check(void *arg UNUSED)
1599{
1600 return 0;
1601}
1602
1603 static PyObject *
1604OptionsNew(int opt_type, void *from, checkfun Check, PyObject *fromObj)
1605{
1606 OptionsObject *self;
1607
Bram Moolenaar774267b2013-05-21 20:51:59 +02001608 self = PyObject_GC_New(OptionsObject, &OptionsType);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001609 if (self == NULL)
1610 return NULL;
1611
1612 self->opt_type = opt_type;
1613 self->from = from;
1614 self->Check = Check;
1615 self->fromObj = fromObj;
1616 if (fromObj)
1617 Py_INCREF(fromObj);
1618
1619 return (PyObject *)(self);
1620}
1621
1622 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001623OptionsDestructor(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001624{
Bram Moolenaar774267b2013-05-21 20:51:59 +02001625 PyObject_GC_UnTrack((void *)(self));
1626 Py_XDECREF(self->fromObj);
1627 PyObject_GC_Del((void *)(self));
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001628}
1629
1630 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001631OptionsTraverse(OptionsObject *self, visitproc visit, void *arg)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001632{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001633 Py_VISIT(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001634 return 0;
1635}
1636
1637 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001638OptionsClear(OptionsObject *self)
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001639{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001640 Py_CLEAR(self->fromObj);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02001641 return 0;
1642}
1643
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001644 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001645OptionsItem(OptionsObject *self, PyObject *keyObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001646{
1647 char_u *key;
1648 int flags;
1649 long numval;
1650 char_u *stringval;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001651 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001652
Bram Moolenaard6e39182013-05-21 18:30:34 +02001653 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001654 return NULL;
1655
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001656 DICTKEY_GET_NOTEMPTY(NULL)
1657
1658 flags = get_option_value_strict(key, &numval, &stringval,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001659 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001660
1661 DICTKEY_UNREF
1662
1663 if (flags == 0)
1664 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001665 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001666 return NULL;
1667 }
1668
1669 if (flags & SOPT_UNSET)
1670 {
1671 Py_INCREF(Py_None);
1672 return Py_None;
1673 }
1674 else if (flags & SOPT_BOOL)
1675 {
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001676 PyObject *r;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001677 r = numval ? Py_True : Py_False;
1678 Py_INCREF(r);
1679 return r;
1680 }
1681 else if (flags & SOPT_NUM)
1682 return PyInt_FromLong(numval);
1683 else if (flags & SOPT_STRING)
1684 {
1685 if (stringval)
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001686 {
1687 PyObject *r = PyBytes_FromString((char *) stringval);
1688 vim_free(stringval);
1689 return r;
1690 }
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001691 else
1692 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001693 PyErr_SetString(PyExc_RuntimeError,
1694 _("unable to get option value"));
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001695 return NULL;
1696 }
1697 }
1698 else
1699 {
1700 PyErr_SetVim("Internal error: unknown option type. Should not happen");
1701 return NULL;
1702 }
1703}
1704
1705 static int
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001706set_option_value_err(key, numval, stringval, opt_flags)
1707 char_u *key;
1708 int numval;
1709 char_u *stringval;
1710 int opt_flags;
1711{
1712 char_u *errmsg;
1713
1714 if ((errmsg = set_option_value(key, numval, stringval, opt_flags)))
1715 {
1716 if (VimTryEnd())
1717 return FAIL;
1718 PyErr_SetVim((char *)errmsg);
1719 return FAIL;
1720 }
1721 return OK;
1722}
1723
1724 static int
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001725set_option_value_for(key, numval, stringval, opt_flags, opt_type, from)
1726 char_u *key;
1727 int numval;
1728 char_u *stringval;
1729 int opt_flags;
1730 int opt_type;
1731 void *from;
1732{
Bram Moolenaar0b9aecc2013-05-21 22:13:41 +02001733 win_T *save_curwin = NULL;
1734 tabpage_T *save_curtab = NULL;
1735 buf_T *save_curbuf = NULL;
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001736 int r = 0;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001737
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001738 VimTryStart();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001739 switch (opt_type)
1740 {
1741 case SREQ_WIN:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001742 if (switch_win(&save_curwin, &save_curtab, (win_T *)from,
1743 win_find_tabpage((win_T *)from)) == FAIL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001744 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001745 if (VimTryEnd())
1746 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001747 PyErr_SetVim("Problem while switching windows.");
1748 return -1;
1749 }
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001750 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001751 restore_win(save_curwin, save_curtab);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001752 if (r == FAIL)
1753 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001754 break;
1755 case SREQ_BUF:
Bram Moolenaar105bc352013-05-17 16:03:57 +02001756 switch_buffer(&save_curbuf, (buf_T *)from);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001757 r = set_option_value_err(key, numval, stringval, opt_flags);
Bram Moolenaar105bc352013-05-17 16:03:57 +02001758 restore_buffer(save_curbuf);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001759 if (r == FAIL)
1760 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001761 break;
1762 case SREQ_GLOBAL:
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001763 r = set_option_value_err(key, numval, stringval, opt_flags);
1764 if (r == FAIL)
1765 return -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001766 break;
1767 }
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02001768 return VimTryEnd();
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001769}
1770
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001771 static void *
1772py_memsave(void *p, size_t len)
1773{
1774 void *r;
1775 if (!(r = PyMem_Malloc(len)))
1776 return NULL;
1777 mch_memmove(r, p, len);
1778 return r;
1779}
1780
1781#define PY_STRSAVE(s) ((char_u *) py_memsave(s, STRLEN(s) + 1))
1782
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001783 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001784OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001785{
1786 char_u *key;
1787 int flags;
1788 int opt_flags;
1789 int r = 0;
Bram Moolenaar161fb5e2013-05-06 06:26:15 +02001790 DICTKEY_DECL
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001791
Bram Moolenaard6e39182013-05-21 18:30:34 +02001792 if (self->Check(self->from))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001793 return -1;
1794
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001795 DICTKEY_GET_NOTEMPTY(-1)
1796
1797 flags = get_option_value_strict(key, NULL, NULL,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001798 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001799
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001800 if (flags == 0)
1801 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02001802 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001803 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001804 return -1;
1805 }
1806
1807 if (valObject == NULL)
1808 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001809 if (self->opt_type == SREQ_GLOBAL)
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001810 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001811 PyErr_SetString(PyExc_ValueError,
1812 _("unable to unset global option"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001813 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001814 return -1;
1815 }
1816 else if (!(flags & SOPT_GLOBAL))
1817 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001818 PyErr_SetString(PyExc_ValueError, _("unable to unset option "
1819 "without global value"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001820 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001821 return -1;
1822 }
1823 else
1824 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02001825 unset_global_local_option(key, self->from);
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001826 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001827 return 0;
1828 }
1829 }
1830
Bram Moolenaard6e39182013-05-21 18:30:34 +02001831 opt_flags = (self->opt_type ? OPT_LOCAL : OPT_GLOBAL);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001832
1833 if (flags & SOPT_BOOL)
1834 {
Bram Moolenaarb983f752013-05-15 16:11:50 +02001835 int istrue = PyObject_IsTrue(valObject);
Bram Moolenaarc96ebe72013-05-21 22:38:18 +02001836
Bram Moolenaarb983f752013-05-15 16:11:50 +02001837 if (istrue == -1)
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001838 r = -1;
1839 else
1840 r = set_option_value_for(key, istrue, NULL,
1841 opt_flags, self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001842 }
1843 else if (flags & SOPT_NUM)
1844 {
1845 int val;
1846
1847#if PY_MAJOR_VERSION < 3
1848 if (PyInt_Check(valObject))
1849 val = PyInt_AsLong(valObject);
1850 else
1851#endif
1852 if (PyLong_Check(valObject))
1853 val = PyLong_AsLong(valObject);
1854 else
1855 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02001856 PyErr_SetString(PyExc_TypeError, _("object must be integer"));
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001857 DICTKEY_UNREF
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001858 return -1;
1859 }
1860
1861 r = set_option_value_for(key, val, NULL, opt_flags,
Bram Moolenaard6e39182013-05-21 18:30:34 +02001862 self->opt_type, self->from);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001863 }
1864 else
1865 {
1866 char_u *val;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001867 PyObject *todecref;
1868
1869 if ((val = StringToChars(valObject, &todecref)))
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001870 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001871 r = set_option_value_for(key, 0, val, opt_flags,
1872 self->opt_type, self->from);
1873 Py_XDECREF(todecref);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001874 }
1875 else
Bram Moolenaare9ba5162013-05-29 22:02:22 +02001876 r = -1;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001877 }
1878
Bram Moolenaar1bc24282013-05-29 21:37:35 +02001879 DICTKEY_UNREF
1880
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001881 return r;
1882}
1883
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02001884static PyMappingMethods OptionsAsMapping = {
1885 (lenfunc) NULL,
1886 (binaryfunc) OptionsItem,
1887 (objobjargproc) OptionsAssItem,
1888};
1889
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001890/* Tabpage object
1891 */
1892
1893typedef struct
1894{
1895 PyObject_HEAD
1896 tabpage_T *tab;
1897} TabPageObject;
1898
1899static PyObject *WinListNew(TabPageObject *tabObject);
1900
1901static PyTypeObject TabPageType;
1902
1903 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02001904CheckTabPage(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001905{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001906 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001907 {
1908 PyErr_SetVim(_("attempt to refer to deleted tab page"));
1909 return -1;
1910 }
1911
1912 return 0;
1913}
1914
1915 static PyObject *
1916TabPageNew(tabpage_T *tab)
1917{
1918 TabPageObject *self;
1919
1920 if (TAB_PYTHON_REF(tab))
1921 {
1922 self = TAB_PYTHON_REF(tab);
1923 Py_INCREF(self);
1924 }
1925 else
1926 {
1927 self = PyObject_NEW(TabPageObject, &TabPageType);
1928 if (self == NULL)
1929 return NULL;
1930 self->tab = tab;
1931 TAB_PYTHON_REF(tab) = self;
1932 }
1933
1934 return (PyObject *)(self);
1935}
1936
1937 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02001938TabPageDestructor(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001939{
Bram Moolenaard6e39182013-05-21 18:30:34 +02001940 if (self->tab && self->tab != INVALID_TABPAGE_VALUE)
1941 TAB_PYTHON_REF(self->tab) = NULL;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001942
1943 DESTRUCTOR_FINISH(self);
1944}
1945
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001946static char *TabPageAttrs[] = {
1947 "windows", "number", "vars", "window", "valid",
1948 NULL
1949};
1950
1951 static PyObject *
1952TabPageDir(PyObject *self)
1953{
1954 return ObjectDir(self, TabPageAttrs);
1955}
1956
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001957 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02001958TabPageAttrValid(TabPageObject *self, char *name)
1959{
1960 PyObject *r;
1961
1962 if (strcmp(name, "valid") != 0)
1963 return NULL;
1964
1965 r = ((self->tab == INVALID_TABPAGE_VALUE) ? Py_False : Py_True);
1966 Py_INCREF(r);
1967 return r;
1968}
1969
1970 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001971TabPageAttr(TabPageObject *self, char *name)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001972{
1973 if (strcmp(name, "windows") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001974 return WinListNew(self);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001975 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001976 return PyLong_FromLong((long) get_tab_number(self->tab));
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001977 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02001978 return DictionaryNew(self->tab->tp_vars);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001979 else if (strcmp(name, "window") == 0)
1980 {
1981 /* For current tab window.c does not bother to set or update tp_curwin
1982 */
Bram Moolenaard6e39182013-05-21 18:30:34 +02001983 if (self->tab == curtab)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02001984 return WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001985 else
Bram Moolenaard6e39182013-05-21 18:30:34 +02001986 return WindowNew(self->tab->tp_curwin, self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001987 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02001988 else if (strcmp(name, "__members__") == 0)
1989 return ObjectDir(NULL, TabPageAttrs);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001990 return NULL;
1991}
1992
1993 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02001994TabPageRepr(TabPageObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001995{
1996 static char repr[100];
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001997
Bram Moolenaard6e39182013-05-21 18:30:34 +02001998 if (self->tab == INVALID_TABPAGE_VALUE)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02001999 {
2000 vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
2001 return PyString_FromString(repr);
2002 }
2003 else
2004 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002005 int t = get_tab_number(self->tab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002006
2007 if (t == 0)
2008 vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
2009 (self));
2010 else
2011 vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
2012
2013 return PyString_FromString(repr);
2014 }
2015}
2016
2017static struct PyMethodDef TabPageMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002018 /* name, function, calling, documentation */
2019 {"__dir__", (PyCFunction)TabPageDir, METH_NOARGS, ""},
2020 { NULL, NULL, 0, NULL}
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002021};
2022
2023/*
2024 * Window list object
2025 */
2026
2027static PyTypeObject TabListType;
2028static PySequenceMethods TabListAsSeq;
2029
2030typedef struct
2031{
2032 PyObject_HEAD
2033} TabListObject;
2034
2035 static PyInt
2036TabListLength(PyObject *self UNUSED)
2037{
2038 tabpage_T *tp = first_tabpage;
2039 PyInt n = 0;
2040
2041 while (tp != NULL)
2042 {
2043 ++n;
2044 tp = tp->tp_next;
2045 }
2046
2047 return n;
2048}
2049
2050 static PyObject *
2051TabListItem(PyObject *self UNUSED, PyInt n)
2052{
2053 tabpage_T *tp;
2054
2055 for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
2056 if (n == 0)
2057 return TabPageNew(tp);
2058
2059 PyErr_SetString(PyExc_IndexError, _("no such tab page"));
2060 return NULL;
2061}
2062
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002063/* Window object
2064 */
2065
2066typedef struct
2067{
2068 PyObject_HEAD
2069 win_T *win;
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002070 TabPageObject *tabObject;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002071} WindowObject;
2072
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002073static PyTypeObject WindowType;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002074
2075 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002076CheckWindow(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002077{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002078 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002079 {
2080 PyErr_SetVim(_("attempt to refer to deleted window"));
2081 return -1;
2082 }
2083
2084 return 0;
2085}
2086
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002087 static PyObject *
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002088WindowNew(win_T *win, tabpage_T *tab)
Bram Moolenaar971db462013-05-12 18:44:48 +02002089{
2090 /* We need to handle deletion of windows underneath us.
2091 * If we add a "w_python*_ref" field to the win_T structure,
2092 * then we can get at it in win_free() in vim. We then
2093 * need to create only ONE Python object per window - if
2094 * we try to create a second, just INCREF the existing one
2095 * and return it. The (single) Python object referring to
2096 * the window is stored in "w_python*_ref".
2097 * On a win_free() we set the Python object's win_T* field
2098 * to an invalid value. We trap all uses of a window
2099 * object, and reject them if the win_T* field is invalid.
2100 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002101 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02002102 * w_python_ref and w_python3_ref fields respectively.
2103 */
2104
2105 WindowObject *self;
2106
2107 if (WIN_PYTHON_REF(win))
2108 {
2109 self = WIN_PYTHON_REF(win);
2110 Py_INCREF(self);
2111 }
2112 else
2113 {
Bram Moolenaar774267b2013-05-21 20:51:59 +02002114 self = PyObject_GC_New(WindowObject, &WindowType);
Bram Moolenaar971db462013-05-12 18:44:48 +02002115 if (self == NULL)
2116 return NULL;
2117 self->win = win;
2118 WIN_PYTHON_REF(win) = self;
2119 }
2120
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002121 self->tabObject = ((TabPageObject *)(TabPageNew(tab)));
2122
Bram Moolenaar971db462013-05-12 18:44:48 +02002123 return (PyObject *)(self);
2124}
2125
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002126 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002127WindowDestructor(WindowObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002128{
Bram Moolenaar774267b2013-05-21 20:51:59 +02002129 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaard6e39182013-05-21 18:30:34 +02002130 if (self->win && self->win != INVALID_WINDOW_VALUE)
2131 WIN_PYTHON_REF(self->win) = NULL;
Bram Moolenaar774267b2013-05-21 20:51:59 +02002132 Py_XDECREF(((PyObject *)(self->tabObject)));
2133 PyObject_GC_Del((void *)(self));
2134}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002135
Bram Moolenaar774267b2013-05-21 20:51:59 +02002136 static int
2137WindowTraverse(WindowObject *self, visitproc visit, void *arg)
2138{
2139 Py_VISIT(((PyObject *)(self->tabObject)));
2140 return 0;
2141}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002142
Bram Moolenaar774267b2013-05-21 20:51:59 +02002143 static int
2144WindowClear(WindowObject *self)
2145{
2146 Py_CLEAR(self->tabObject);
2147 return 0;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002148}
2149
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002150 static win_T *
2151get_firstwin(TabPageObject *tabObject)
2152{
2153 if (tabObject)
2154 {
2155 if (CheckTabPage(tabObject))
2156 return NULL;
2157 /* For current tab window.c does not bother to set or update tp_firstwin
2158 */
2159 else if (tabObject->tab == curtab)
2160 return firstwin;
2161 else
2162 return tabObject->tab->tp_firstwin;
2163 }
2164 else
2165 return firstwin;
2166}
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002167static char *WindowAttrs[] = {
2168 "buffer", "cursor", "height", "vars", "options", "number", "row", "col",
2169 "tabpage", "valid",
2170 NULL
2171};
2172
2173 static PyObject *
2174WindowDir(PyObject *self)
2175{
2176 return ObjectDir(self, WindowAttrs);
2177}
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002178
Bram Moolenaar971db462013-05-12 18:44:48 +02002179 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02002180WindowAttrValid(WindowObject *self, char *name)
2181{
2182 PyObject *r;
2183
2184 if (strcmp(name, "valid") != 0)
2185 return NULL;
2186
2187 r = ((self->win == INVALID_WINDOW_VALUE) ? Py_False : Py_True);
2188 Py_INCREF(r);
2189 return r;
2190}
2191
2192 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002193WindowAttr(WindowObject *self, char *name)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002194{
2195 if (strcmp(name, "buffer") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002196 return (PyObject *)BufferNew(self->win->w_buffer);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002197 else if (strcmp(name, "cursor") == 0)
2198 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002199 pos_T *pos = &self->win->w_cursor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002200
2201 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
2202 }
2203 else if (strcmp(name, "height") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002204 return PyLong_FromLong((long)(self->win->w_height));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002205#ifdef FEAT_WINDOWS
2206 else if (strcmp(name, "row") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002207 return PyLong_FromLong((long)(self->win->w_winrow));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002208#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002209#ifdef FEAT_VERTSPLIT
2210 else if (strcmp(name, "width") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002211 return PyLong_FromLong((long)(W_WIDTH(self->win)));
Bram Moolenaar4e5dfb52013-05-12 19:30:31 +02002212 else if (strcmp(name, "col") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002213 return PyLong_FromLong((long)(W_WINCOL(self->win)));
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002214#endif
Bram Moolenaar230bb3f2013-04-24 14:07:45 +02002215 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002216 return DictionaryNew(self->win->w_vars);
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02002217 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002218 return OptionsNew(SREQ_WIN, self->win, (checkfun) CheckWindow,
2219 (PyObject *) self);
Bram Moolenaar6d216452013-05-12 19:00:41 +02002220 else if (strcmp(name, "number") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002221 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002222 if (CheckTabPage(self->tabObject))
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002223 return NULL;
2224 return PyLong_FromLong((long)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002225 get_win_number(self->win, get_firstwin(self->tabObject)));
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002226 }
2227 else if (strcmp(name, "tabpage") == 0)
2228 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002229 Py_INCREF(self->tabObject);
2230 return (PyObject *)(self->tabObject);
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02002231 }
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002232 else if (strcmp(name, "__members__") == 0)
2233 return ObjectDir(NULL, WindowAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002234 else
2235 return NULL;
2236}
2237
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002238 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02002239WindowSetattr(WindowObject *self, char *name, PyObject *val)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002240{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002241 if (CheckWindow(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002242 return -1;
2243
2244 if (strcmp(name, "buffer") == 0)
2245 {
2246 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
2247 return -1;
2248 }
2249 else if (strcmp(name, "cursor") == 0)
2250 {
2251 long lnum;
2252 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002253
2254 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
2255 return -1;
2256
Bram Moolenaard6e39182013-05-21 18:30:34 +02002257 if (lnum <= 0 || lnum > self->win->w_buffer->b_ml.ml_line_count)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002258 {
2259 PyErr_SetVim(_("cursor position outside buffer"));
2260 return -1;
2261 }
2262
2263 /* Check for keyboard interrupts */
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002264 if (VimCheckInterrupt())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002265 return -1;
2266
Bram Moolenaard6e39182013-05-21 18:30:34 +02002267 self->win->w_cursor.lnum = lnum;
2268 self->win->w_cursor.col = col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002269#ifdef FEAT_VIRTUALEDIT
Bram Moolenaard6e39182013-05-21 18:30:34 +02002270 self->win->w_cursor.coladd = 0;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002271#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002272 /* When column is out of range silently correct it. */
Bram Moolenaard6e39182013-05-21 18:30:34 +02002273 check_cursor_col_win(self->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002274
Bram Moolenaar03a807a2011-07-07 15:08:58 +02002275 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002276 return 0;
2277 }
2278 else if (strcmp(name, "height") == 0)
2279 {
2280 int height;
2281 win_T *savewin;
2282
2283 if (!PyArg_Parse(val, "i", &height))
2284 return -1;
2285
2286#ifdef FEAT_GUI
2287 need_mouse_correct = TRUE;
2288#endif
2289 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002290 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002291
2292 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002293 win_setheight(height);
2294 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002295 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002296 return -1;
2297
2298 return 0;
2299 }
2300#ifdef FEAT_VERTSPLIT
2301 else if (strcmp(name, "width") == 0)
2302 {
2303 int width;
2304 win_T *savewin;
2305
2306 if (!PyArg_Parse(val, "i", &width))
2307 return -1;
2308
2309#ifdef FEAT_GUI
2310 need_mouse_correct = TRUE;
2311#endif
2312 savewin = curwin;
Bram Moolenaard6e39182013-05-21 18:30:34 +02002313 curwin = self->win;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002314
2315 VimTryStart();
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002316 win_setwidth(width);
2317 curwin = savewin;
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002318 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002319 return -1;
2320
2321 return 0;
2322 }
2323#endif
2324 else
2325 {
2326 PyErr_SetString(PyExc_AttributeError, name);
2327 return -1;
2328 }
2329}
2330
2331 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002332WindowRepr(WindowObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002333{
2334 static char repr[100];
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002335
Bram Moolenaard6e39182013-05-21 18:30:34 +02002336 if (self->win == INVALID_WINDOW_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002337 {
2338 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
2339 return PyString_FromString(repr);
2340 }
2341 else
2342 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02002343 int w = get_win_number(self->win, firstwin);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002344
Bram Moolenaar6d216452013-05-12 19:00:41 +02002345 if (w == 0)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002346 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
2347 (self));
2348 else
Bram Moolenaar6d216452013-05-12 19:00:41 +02002349 vim_snprintf(repr, 100, _("<window %d>"), w - 1);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002350
2351 return PyString_FromString(repr);
2352 }
2353}
2354
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002355static struct PyMethodDef WindowMethods[] = {
Bram Moolenaardd8aca62013-05-29 22:36:10 +02002356 /* name, function, calling, documentation */
2357 {"__dir__", (PyCFunction)WindowDir, METH_NOARGS, ""},
2358 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002359};
2360
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002361/*
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002362 * Window list object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002363 */
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002364
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02002365static PyTypeObject WinListType;
2366static PySequenceMethods WinListAsSeq;
2367
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002368typedef struct
2369{
2370 PyObject_HEAD
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002371 TabPageObject *tabObject;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02002372} WinListObject;
2373
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002374 static PyObject *
2375WinListNew(TabPageObject *tabObject)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002376{
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002377 WinListObject *self;
2378
2379 self = PyObject_NEW(WinListObject, &WinListType);
2380 self->tabObject = tabObject;
2381 Py_INCREF(tabObject);
2382
2383 return (PyObject *)(self);
2384}
2385
2386 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02002387WinListDestructor(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002388{
Bram Moolenaard6e39182013-05-21 18:30:34 +02002389 TabPageObject *tabObject = self->tabObject;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002390
2391 if (tabObject)
Bram Moolenaar425154d2013-05-24 18:58:43 +02002392 {
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002393 Py_DECREF((PyObject *)(tabObject));
Bram Moolenaar425154d2013-05-24 18:58:43 +02002394 }
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002395
2396 DESTRUCTOR_FINISH(self);
2397}
2398
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002399 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02002400WinListLength(WinListObject *self)
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002401{
2402 win_T *w;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002403 PyInt n = 0;
2404
Bram Moolenaard6e39182013-05-21 18:30:34 +02002405 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002406 return -1;
2407
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002408 while (w != NULL)
2409 {
2410 ++n;
2411 w = W_NEXT(w);
2412 }
2413
2414 return n;
2415}
2416
2417 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02002418WinListItem(WinListObject *self, PyInt n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002419{
2420 win_T *w;
2421
Bram Moolenaard6e39182013-05-21 18:30:34 +02002422 if (!(w = get_firstwin(self->tabObject)))
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02002423 return NULL;
2424
2425 for (; w != NULL; w = W_NEXT(w), --n)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002426 if (n == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02002427 return WindowNew(w, self->tabObject? self->tabObject->tab: curtab);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002428
2429 PyErr_SetString(PyExc_IndexError, _("no such window"));
2430 return NULL;
2431}
2432
2433/* Convert a Python string into a Vim line.
2434 *
2435 * The result is in allocated memory. All internal nulls are replaced by
2436 * newline characters. It is an error for the string to contain newline
2437 * characters.
2438 *
2439 * On errors, the Python exception data is set, and NULL is returned.
2440 */
2441 static char *
2442StringToLine(PyObject *obj)
2443{
2444 const char *str;
2445 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002446 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002447 PyInt len;
2448 PyInt i;
2449 char *p;
2450
2451 if (obj == NULL || !PyString_Check(obj))
2452 {
2453 PyErr_BadArgument();
2454 return NULL;
2455 }
2456
Bram Moolenaar19e60942011-06-19 00:27:51 +02002457 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
2458 str = PyString_AsString(bytes);
2459 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002460
2461 /*
2462 * Error checking: String must not contain newlines, as we
2463 * are replacing a single line, and we must replace it with
2464 * a single line.
2465 * A trailing newline is removed, so that append(f.readlines()) works.
2466 */
2467 p = memchr(str, '\n', len);
2468 if (p != NULL)
2469 {
2470 if (p == str + len - 1)
2471 --len;
2472 else
2473 {
2474 PyErr_SetVim(_("string cannot contain newlines"));
2475 return NULL;
2476 }
2477 }
2478
2479 /* Create a copy of the string, with internal nulls replaced by
2480 * newline characters, as is the vim convention.
2481 */
2482 save = (char *)alloc((unsigned)(len+1));
2483 if (save == NULL)
2484 {
2485 PyErr_NoMemory();
2486 return NULL;
2487 }
2488
2489 for (i = 0; i < len; ++i)
2490 {
2491 if (str[i] == '\0')
2492 save[i] = '\n';
2493 else
2494 save[i] = str[i];
2495 }
2496
2497 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +02002498 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002499
2500 return save;
2501}
2502
2503/* Get a line from the specified buffer. The line number is
2504 * in Vim format (1-based). The line is returned as a Python
2505 * string object.
2506 */
2507 static PyObject *
2508GetBufferLine(buf_T *buf, PyInt n)
2509{
2510 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2511}
2512
2513
2514/* Get a list of lines from the specified buffer. The line numbers
2515 * are in Vim format (1-based). The range is from lo up to, but not
2516 * including, hi. The list is returned as a Python list of string objects.
2517 */
2518 static PyObject *
2519GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
2520{
2521 PyInt i;
2522 PyInt n = hi - lo;
2523 PyObject *list = PyList_New(n);
2524
2525 if (list == NULL)
2526 return NULL;
2527
2528 for (i = 0; i < n; ++i)
2529 {
2530 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2531
2532 /* Error check - was the Python string creation OK? */
2533 if (str == NULL)
2534 {
2535 Py_DECREF(list);
2536 return NULL;
2537 }
2538
2539 /* Set the list item */
2540 if (PyList_SetItem(list, i, str))
2541 {
2542 Py_DECREF(str);
2543 Py_DECREF(list);
2544 return NULL;
2545 }
2546 }
2547
2548 /* The ownership of the Python list is passed to the caller (ie,
2549 * the caller should Py_DECREF() the object when it is finished
2550 * with it).
2551 */
2552
2553 return list;
2554}
2555
2556/*
2557 * Check if deleting lines made the cursor position invalid.
2558 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2559 * deleted).
2560 */
2561 static void
2562py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
2563{
2564 if (curwin->w_cursor.lnum >= lo)
2565 {
2566 /* Adjust the cursor position if it's in/after the changed
2567 * lines. */
2568 if (curwin->w_cursor.lnum >= hi)
2569 {
2570 curwin->w_cursor.lnum += extra;
2571 check_cursor_col();
2572 }
2573 else if (extra < 0)
2574 {
2575 curwin->w_cursor.lnum = lo;
2576 check_cursor();
2577 }
2578 else
2579 check_cursor_col();
2580 changed_cline_bef_curs();
2581 }
2582 invalidate_botline();
2583}
2584
Bram Moolenaar19e60942011-06-19 00:27:51 +02002585/*
2586 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002587 * in Vim format (1-based). The replacement line is given as
2588 * a Python string object. The object is checked for validity
2589 * and correct format. Errors are returned as a value of FAIL.
2590 * The return value is OK on success.
2591 * If OK is returned and len_change is not NULL, *len_change
2592 * is set to the change in the buffer length.
2593 */
2594 static int
2595SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
2596{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002597 /* First of all, we check the type of the supplied Python object.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002598 * There are three cases:
2599 * 1. NULL, or None - this is a deletion.
2600 * 2. A string - this is a replacement.
2601 * 3. Anything else - this is an error.
2602 */
2603 if (line == Py_None || line == NULL)
2604 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002605 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002606
2607 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002608 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002609
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002610 VimTryStart();
2611
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002612 if (u_savedel((linenr_T)n, 1L) == FAIL)
2613 PyErr_SetVim(_("cannot save undo information"));
2614 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2615 PyErr_SetVim(_("cannot delete line"));
2616 else
2617 {
Bram Moolenaar105bc352013-05-17 16:03:57 +02002618 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002619 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
2620 deleted_lines_mark((linenr_T)n, 1L);
2621 }
2622
Bram Moolenaar105bc352013-05-17 16:03:57 +02002623 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002624
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002625 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002626 return FAIL;
2627
2628 if (len_change)
2629 *len_change = -1;
2630
2631 return OK;
2632 }
2633 else if (PyString_Check(line))
2634 {
2635 char *save = StringToLine(line);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002636 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002637
2638 if (save == NULL)
2639 return FAIL;
2640
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002641 VimTryStart();
2642
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002643 /* We do not need to free "save" if ml_replace() consumes it. */
2644 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002645 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002646
2647 if (u_savesub((linenr_T)n) == FAIL)
2648 {
2649 PyErr_SetVim(_("cannot save undo information"));
2650 vim_free(save);
2651 }
2652 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2653 {
2654 PyErr_SetVim(_("cannot replace line"));
2655 vim_free(save);
2656 }
2657 else
2658 changed_bytes((linenr_T)n, 0);
2659
Bram Moolenaar105bc352013-05-17 16:03:57 +02002660 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002661
2662 /* Check that the cursor is not beyond the end of the line now. */
Bram Moolenaar105bc352013-05-17 16:03:57 +02002663 if (buf == savebuf)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002664 check_cursor_col();
2665
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002666 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002667 return FAIL;
2668
2669 if (len_change)
2670 *len_change = 0;
2671
2672 return OK;
2673 }
2674 else
2675 {
2676 PyErr_BadArgument();
2677 return FAIL;
2678 }
2679}
2680
Bram Moolenaar19e60942011-06-19 00:27:51 +02002681/* Replace a range of lines in the specified buffer. The line numbers are in
2682 * Vim format (1-based). The range is from lo up to, but not including, hi.
2683 * The replacement lines are given as a Python list of string objects. The
2684 * list is checked for validity and correct format. Errors are returned as a
2685 * value of FAIL. The return value is OK on success.
2686 * If OK is returned and len_change is not NULL, *len_change
2687 * is set to the change in the buffer length.
2688 */
2689 static int
2690SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
2691{
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002692 /* First of all, we check the type of the supplied Python object.
Bram Moolenaar19e60942011-06-19 00:27:51 +02002693 * There are three cases:
2694 * 1. NULL, or None - this is a deletion.
2695 * 2. A list - this is a replacement.
2696 * 3. Anything else - this is an error.
2697 */
2698 if (list == Py_None || list == NULL)
2699 {
2700 PyInt i;
2701 PyInt n = (int)(hi - lo);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002702 buf_T *savebuf;
Bram Moolenaar19e60942011-06-19 00:27:51 +02002703
2704 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002705 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002706 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002707
2708 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2709 PyErr_SetVim(_("cannot save undo information"));
2710 else
2711 {
2712 for (i = 0; i < n; ++i)
2713 {
2714 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2715 {
2716 PyErr_SetVim(_("cannot delete line"));
2717 break;
2718 }
2719 }
Bram Moolenaar105bc352013-05-17 16:03:57 +02002720 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002721 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
2722 deleted_lines_mark((linenr_T)lo, (long)i);
2723 }
2724
Bram Moolenaar105bc352013-05-17 16:03:57 +02002725 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002726
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002727 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002728 return FAIL;
2729
2730 if (len_change)
2731 *len_change = -n;
2732
2733 return OK;
2734 }
2735 else if (PyList_Check(list))
2736 {
2737 PyInt i;
2738 PyInt new_len = PyList_Size(list);
2739 PyInt old_len = hi - lo;
2740 PyInt extra = 0; /* lines added to text, can be negative */
2741 char **array;
2742 buf_T *savebuf;
2743
2744 if (new_len == 0) /* avoid allocating zero bytes */
2745 array = NULL;
2746 else
2747 {
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002748 array = PyMem_New(char *, new_len);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002749 if (array == NULL)
2750 {
2751 PyErr_NoMemory();
2752 return FAIL;
2753 }
2754 }
2755
2756 for (i = 0; i < new_len; ++i)
2757 {
2758 PyObject *line = PyList_GetItem(list, i);
2759
2760 array[i] = StringToLine(line);
2761 if (array[i] == NULL)
2762 {
2763 while (i)
2764 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002765 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002766 return FAIL;
2767 }
2768 }
2769
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002770 VimTryStart();
Bram Moolenaar19e60942011-06-19 00:27:51 +02002771 PyErr_Clear();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002772
2773 // START of region without "return". Must call restore_buffer()!
2774 switch_buffer(&savebuf, buf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002775
2776 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2777 PyErr_SetVim(_("cannot save undo information"));
2778
2779 /* If the size of the range is reducing (ie, new_len < old_len) we
2780 * need to delete some old_len. We do this at the start, by
2781 * repeatedly deleting line "lo".
2782 */
2783 if (!PyErr_Occurred())
2784 {
2785 for (i = 0; i < old_len - new_len; ++i)
2786 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2787 {
2788 PyErr_SetVim(_("cannot delete line"));
2789 break;
2790 }
2791 extra -= i;
2792 }
2793
2794 /* For as long as possible, replace the existing old_len with the
2795 * new old_len. This is a more efficient operation, as it requires
2796 * less memory allocation and freeing.
2797 */
2798 if (!PyErr_Occurred())
2799 {
2800 for (i = 0; i < old_len && i < new_len; ++i)
2801 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2802 == FAIL)
2803 {
2804 PyErr_SetVim(_("cannot replace line"));
2805 break;
2806 }
2807 }
2808 else
2809 i = 0;
2810
2811 /* Now we may need to insert the remaining new old_len. If we do, we
2812 * must free the strings as we finish with them (we can't pass the
2813 * responsibility to vim in this case).
2814 */
2815 if (!PyErr_Occurred())
2816 {
2817 while (i < new_len)
2818 {
2819 if (ml_append((linenr_T)(lo + i - 1),
2820 (char_u *)array[i], 0, FALSE) == FAIL)
2821 {
2822 PyErr_SetVim(_("cannot insert line"));
2823 break;
2824 }
2825 vim_free(array[i]);
2826 ++i;
2827 ++extra;
2828 }
2829 }
2830
2831 /* Free any left-over old_len, as a result of an error */
2832 while (i < new_len)
2833 {
2834 vim_free(array[i]);
2835 ++i;
2836 }
2837
2838 /* Free the array of old_len. All of its contents have now
2839 * been dealt with (either freed, or the responsibility passed
2840 * to vim.
2841 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002842 PyMem_Free(array);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002843
2844 /* Adjust marks. Invalidate any which lie in the
2845 * changed range, and move any in the remainder of the buffer.
2846 */
2847 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2848 (long)MAXLNUM, (long)extra);
2849 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2850
Bram Moolenaar105bc352013-05-17 16:03:57 +02002851 if (buf == savebuf)
Bram Moolenaar19e60942011-06-19 00:27:51 +02002852 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
2853
Bram Moolenaar105bc352013-05-17 16:03:57 +02002854 // END of region without "return".
2855 restore_buffer(savebuf);
Bram Moolenaar19e60942011-06-19 00:27:51 +02002856
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002857 if (VimTryEnd())
Bram Moolenaar19e60942011-06-19 00:27:51 +02002858 return FAIL;
2859
2860 if (len_change)
2861 *len_change = new_len - old_len;
2862
2863 return OK;
2864 }
2865 else
2866 {
2867 PyErr_BadArgument();
2868 return FAIL;
2869 }
2870}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002871
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02002872/* Insert a number of lines into the specified buffer after the specified line.
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002873 * The line number is in Vim format (1-based). The lines to be inserted are
2874 * given as a Python list of string objects or as a single string. The lines
2875 * to be added are checked for validity and correct format. Errors are
2876 * returned as a value of FAIL. The return value is OK on success.
2877 * If OK is returned and len_change is not NULL, *len_change
2878 * is set to the change in the buffer length.
2879 */
2880 static int
2881InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
2882{
2883 /* First of all, we check the type of the supplied Python object.
2884 * It must be a string or a list, or the call is in error.
2885 */
2886 if (PyString_Check(lines))
2887 {
2888 char *str = StringToLine(lines);
2889 buf_T *savebuf;
2890
2891 if (str == NULL)
2892 return FAIL;
2893
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002894 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002895 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002896 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002897
2898 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2899 PyErr_SetVim(_("cannot save undo information"));
2900 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2901 PyErr_SetVim(_("cannot insert line"));
2902 else
2903 appended_lines_mark((linenr_T)n, 1L);
2904
2905 vim_free(str);
Bram Moolenaar105bc352013-05-17 16:03:57 +02002906 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002907 update_screen(VALID);
2908
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002909 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002910 return FAIL;
2911
2912 if (len_change)
2913 *len_change = 1;
2914
2915 return OK;
2916 }
2917 else if (PyList_Check(lines))
2918 {
2919 PyInt i;
2920 PyInt size = PyList_Size(lines);
2921 char **array;
2922 buf_T *savebuf;
2923
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002924 array = PyMem_New(char *, size);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002925 if (array == NULL)
2926 {
2927 PyErr_NoMemory();
2928 return FAIL;
2929 }
2930
2931 for (i = 0; i < size; ++i)
2932 {
2933 PyObject *line = PyList_GetItem(lines, i);
2934 array[i] = StringToLine(line);
2935
2936 if (array[i] == NULL)
2937 {
2938 while (i)
2939 vim_free(array[--i]);
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002940 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002941 return FAIL;
2942 }
2943 }
2944
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002945 PyErr_Clear();
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002946 VimTryStart();
Bram Moolenaar105bc352013-05-17 16:03:57 +02002947 switch_buffer(&savebuf, buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002948
2949 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2950 PyErr_SetVim(_("cannot save undo information"));
2951 else
2952 {
2953 for (i = 0; i < size; ++i)
2954 {
2955 if (ml_append((linenr_T)(n + i),
2956 (char_u *)array[i], 0, FALSE) == FAIL)
2957 {
2958 PyErr_SetVim(_("cannot insert line"));
2959
2960 /* Free the rest of the lines */
2961 while (i < size)
2962 vim_free(array[i++]);
2963
2964 break;
2965 }
2966 vim_free(array[i]);
2967 }
2968 if (i > 0)
2969 appended_lines_mark((linenr_T)n, (long)i);
2970 }
2971
2972 /* Free the array of lines. All of its contents have now
2973 * been freed.
2974 */
Bram Moolenaare9ba5162013-05-29 22:02:22 +02002975 PyMem_Free(array);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002976
Bram Moolenaar105bc352013-05-17 16:03:57 +02002977 restore_buffer(savebuf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002978 update_screen(VALID);
2979
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02002980 if (VimTryEnd())
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02002981 return FAIL;
2982
2983 if (len_change)
2984 *len_change = size;
2985
2986 return OK;
2987 }
2988 else
2989 {
2990 PyErr_BadArgument();
2991 return FAIL;
2992 }
2993}
2994
2995/*
2996 * Common routines for buffers and line ranges
2997 * -------------------------------------------
2998 */
2999
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003000typedef struct
3001{
3002 PyObject_HEAD
3003 buf_T *buf;
3004} BufferObject;
3005
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003006 static int
Bram Moolenaard6e39182013-05-21 18:30:34 +02003007CheckBuffer(BufferObject *self)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003008{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003009 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003010 {
3011 PyErr_SetVim(_("attempt to refer to deleted buffer"));
3012 return -1;
3013 }
3014
3015 return 0;
3016}
3017
3018 static PyObject *
3019RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
3020{
3021 if (CheckBuffer(self))
3022 return NULL;
3023
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003024 if (end == -1)
3025 end = self->buf->b_ml.ml_line_count;
3026
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003027 if (n < 0)
3028 n += end - start + 1;
3029
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003030 if (n < 0 || n > end - start)
3031 {
3032 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3033 return NULL;
3034 }
3035
3036 return GetBufferLine(self->buf, n+start);
3037}
3038
3039 static PyObject *
3040RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
3041{
3042 PyInt size;
3043
3044 if (CheckBuffer(self))
3045 return NULL;
3046
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003047 if (end == -1)
3048 end = self->buf->b_ml.ml_line_count;
3049
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003050 size = end - start + 1;
3051
3052 if (lo < 0)
3053 lo = 0;
3054 else if (lo > size)
3055 lo = size;
3056 if (hi < 0)
3057 hi = 0;
3058 if (hi < lo)
3059 hi = lo;
3060 else if (hi > size)
3061 hi = size;
3062
3063 return GetBufferLineList(self->buf, lo+start, hi+start);
3064}
3065
3066 static PyInt
3067RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3068{
3069 PyInt len_change;
3070
3071 if (CheckBuffer(self))
3072 return -1;
3073
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003074 if (end == -1)
3075 end = self->buf->b_ml.ml_line_count;
3076
Bram Moolenaarbd80f352013-05-12 21:16:23 +02003077 if (n < 0)
3078 n += end - start + 1;
3079
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003080 if (n < 0 || n > end - start)
3081 {
3082 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
3083 return -1;
3084 }
3085
3086 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
3087 return -1;
3088
3089 if (new_end)
3090 *new_end = end + len_change;
3091
3092 return 0;
3093}
3094
Bram Moolenaar19e60942011-06-19 00:27:51 +02003095 static PyInt
3096RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
3097{
3098 PyInt size;
3099 PyInt len_change;
3100
3101 /* Self must be a valid buffer */
3102 if (CheckBuffer(self))
3103 return -1;
3104
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003105 if (end == -1)
3106 end = self->buf->b_ml.ml_line_count;
3107
Bram Moolenaar19e60942011-06-19 00:27:51 +02003108 /* Sort out the slice range */
3109 size = end - start + 1;
3110
3111 if (lo < 0)
3112 lo = 0;
3113 else if (lo > size)
3114 lo = size;
3115 if (hi < 0)
3116 hi = 0;
3117 if (hi < lo)
3118 hi = lo;
3119 else if (hi > size)
3120 hi = size;
3121
3122 if (SetBufferLineList(self->buf, lo + start, hi + start,
3123 val, &len_change) == FAIL)
3124 return -1;
3125
3126 if (new_end)
3127 *new_end = end + len_change;
3128
3129 return 0;
3130}
3131
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003132
3133 static PyObject *
3134RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
3135{
3136 PyObject *lines;
3137 PyInt len_change;
3138 PyInt max;
3139 PyInt n;
3140
3141 if (CheckBuffer(self))
3142 return NULL;
3143
Bram Moolenaar8f1723d2013-05-12 20:36:14 +02003144 if (end == -1)
3145 end = self->buf->b_ml.ml_line_count;
3146
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003147 max = n = end - start + 1;
3148
3149 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
3150 return NULL;
3151
3152 if (n < 0 || n > max)
3153 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003154 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003155 return NULL;
3156 }
3157
3158 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
3159 return NULL;
3160
3161 if (new_end)
3162 *new_end = end + len_change;
3163
3164 Py_INCREF(Py_None);
3165 return Py_None;
3166}
3167
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003168/* Range object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003169 */
3170
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003171static PyTypeObject RangeType;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003172static PySequenceMethods RangeAsSeq;
3173static PyMappingMethods RangeAsMapping;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003174
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003175typedef struct
3176{
3177 PyObject_HEAD
3178 BufferObject *buf;
3179 PyInt start;
3180 PyInt end;
3181} RangeObject;
3182
3183 static PyObject *
3184RangeNew(buf_T *buf, PyInt start, PyInt end)
3185{
3186 BufferObject *bufr;
3187 RangeObject *self;
Bram Moolenaar774267b2013-05-21 20:51:59 +02003188 self = PyObject_GC_New(RangeObject, &RangeType);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003189 if (self == NULL)
3190 return NULL;
3191
3192 bufr = (BufferObject *)BufferNew(buf);
3193 if (bufr == NULL)
3194 {
3195 Py_DECREF(self);
3196 return NULL;
3197 }
3198 Py_INCREF(bufr);
3199
3200 self->buf = bufr;
3201 self->start = start;
3202 self->end = end;
3203
3204 return (PyObject *)(self);
3205}
3206
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003207 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003208RangeDestructor(RangeObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003209{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003210 PyObject_GC_UnTrack((void *)(self));
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003211 Py_XDECREF(self->buf);
Bram Moolenaar774267b2013-05-21 20:51:59 +02003212 PyObject_GC_Del((void *)(self));
3213}
3214
3215 static int
3216RangeTraverse(RangeObject *self, visitproc visit, void *arg)
3217{
3218 Py_VISIT(((PyObject *)(self->buf)));
3219 return 0;
3220}
3221
3222 static int
3223RangeClear(RangeObject *self)
3224{
3225 Py_CLEAR(self->buf);
3226 return 0;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003227}
3228
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003229 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003230RangeLength(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003231{
3232 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003233 if (CheckBuffer(self->buf))
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003234 return -1; /* ??? */
3235
Bram Moolenaard6e39182013-05-21 18:30:34 +02003236 return (self->end - self->start + 1);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003237}
3238
3239 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003240RangeItem(RangeObject *self, PyInt n)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003241{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003242 return RBItem(self->buf, n, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003243}
3244
3245 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003246RangeSlice(RangeObject *self, PyInt lo, PyInt hi)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003247{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003248 return RBSlice(self->buf, lo, hi, self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003249}
3250
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003251static char *RangeAttrs[] = {
3252 "start", "end",
3253 NULL
3254};
3255
3256 static PyObject *
3257RangeDir(PyObject *self)
3258{
3259 return ObjectDir(self, RangeAttrs);
3260}
3261
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003262 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003263RangeAppend(RangeObject *self, PyObject *args)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003264{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003265 return RBAppend(self->buf, args, self->start, self->end, &self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003266}
3267
3268 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003269RangeRepr(RangeObject *self)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003270{
3271 static char repr[100];
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003272
Bram Moolenaard6e39182013-05-21 18:30:34 +02003273 if (self->buf->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003274 {
3275 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
3276 (self));
3277 return PyString_FromString(repr);
3278 }
3279 else
3280 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003281 char *name = (char *)self->buf->buf->b_fname;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003282 int len;
3283
3284 if (name == NULL)
3285 name = "";
3286 len = (int)strlen(name);
3287
3288 if (len > 45)
3289 name = name + (45 - len);
3290
3291 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
3292 len > 45 ? "..." : "", name,
Bram Moolenaard6e39182013-05-21 18:30:34 +02003293 self->start, self->end);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003294
3295 return PyString_FromString(repr);
3296 }
3297}
3298
3299static struct PyMethodDef RangeMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003300 /* name, function, calling, documentation */
3301 {"append", (PyCFunction)RangeAppend, METH_VARARGS, "Append data to the Vim range" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003302 {"__dir__", (PyCFunction)RangeDir, METH_NOARGS, ""},
3303 { NULL, NULL, 0, NULL}
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003304};
3305
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003306static PyTypeObject BufferType;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003307static PySequenceMethods BufferAsSeq;
3308static PyMappingMethods BufferAsMapping;
3309
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003310 static PyObject *
Bram Moolenaar971db462013-05-12 18:44:48 +02003311BufferNew(buf_T *buf)
3312{
3313 /* We need to handle deletion of buffers underneath us.
3314 * If we add a "b_python*_ref" field to the buf_T structure,
3315 * then we can get at it in buf_freeall() in vim. We then
3316 * need to create only ONE Python object per buffer - if
3317 * we try to create a second, just INCREF the existing one
3318 * and return it. The (single) Python object referring to
3319 * the buffer is stored in "b_python*_ref".
3320 * Question: what to do on a buf_freeall(). We'll probably
3321 * have to either delete the Python object (DECREF it to
3322 * zero - a bad idea, as it leaves dangling refs!) or
3323 * set the buf_T * value to an invalid value (-1?), which
3324 * means we need checks in all access functions... Bah.
3325 *
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003326 * Python2 and Python3 get different fields and different objects:
Bram Moolenaar971db462013-05-12 18:44:48 +02003327 * b_python_ref and b_python3_ref fields respectively.
3328 */
3329
3330 BufferObject *self;
3331
3332 if (BUF_PYTHON_REF(buf) != NULL)
3333 {
3334 self = BUF_PYTHON_REF(buf);
3335 Py_INCREF(self);
3336 }
3337 else
3338 {
3339 self = PyObject_NEW(BufferObject, &BufferType);
3340 if (self == NULL)
3341 return NULL;
3342 self->buf = buf;
3343 BUF_PYTHON_REF(buf) = self;
3344 }
3345
3346 return (PyObject *)(self);
3347}
3348
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003349 static void
Bram Moolenaard6e39182013-05-21 18:30:34 +02003350BufferDestructor(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003351{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003352 if (self->buf && self->buf != INVALID_BUFFER_VALUE)
3353 BUF_PYTHON_REF(self->buf) = NULL;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003354
3355 DESTRUCTOR_FINISH(self);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003356}
3357
Bram Moolenaar971db462013-05-12 18:44:48 +02003358 static PyInt
Bram Moolenaard6e39182013-05-21 18:30:34 +02003359BufferLength(BufferObject *self)
Bram Moolenaar971db462013-05-12 18:44:48 +02003360{
3361 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
Bram Moolenaard6e39182013-05-21 18:30:34 +02003362 if (CheckBuffer(self))
Bram Moolenaar971db462013-05-12 18:44:48 +02003363 return -1; /* ??? */
3364
Bram Moolenaard6e39182013-05-21 18:30:34 +02003365 return (PyInt)(self->buf->b_ml.ml_line_count);
Bram Moolenaar971db462013-05-12 18:44:48 +02003366}
3367
3368 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003369BufferItem(BufferObject *self, PyInt n)
Bram Moolenaar971db462013-05-12 18:44:48 +02003370{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003371 return RBItem(self, n, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003372}
3373
3374 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003375BufferSlice(BufferObject *self, PyInt lo, PyInt hi)
Bram Moolenaar971db462013-05-12 18:44:48 +02003376{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003377 return RBSlice(self, lo, hi, 1, -1);
Bram Moolenaar971db462013-05-12 18:44:48 +02003378}
3379
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003380static char *BufferAttrs[] = {
3381 "name", "number", "vars", "options", "valid",
3382 NULL
3383};
3384
3385 static PyObject *
3386BufferDir(PyObject *self)
3387{
3388 return ObjectDir(self, BufferAttrs);
3389}
3390
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003391 static PyObject *
Bram Moolenaar9e822c02013-05-29 22:15:30 +02003392BufferAttrValid(BufferObject *self, char *name)
3393{
3394 PyObject *r;
3395
3396 if (strcmp(name, "valid") != 0)
3397 return NULL;
3398
3399 r = ((self->buf == INVALID_BUFFER_VALUE) ? Py_False : Py_True);
3400 Py_INCREF(r);
3401 return r;
3402}
3403
3404 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003405BufferAttr(BufferObject *self, char *name)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003406{
3407 if (strcmp(name, "name") == 0)
Bram Moolenaar432b09c2013-05-29 22:26:18 +02003408 return PyString_FromString((self->buf->b_ffname == NULL
3409 ? "" : (char *) self->buf->b_ffname));
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003410 else if (strcmp(name, "number") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003411 return Py_BuildValue(Py_ssize_t_fmt, self->buf->b_fnum);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003412 else if (strcmp(name, "vars") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003413 return DictionaryNew(self->buf->b_vars);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003414 else if (strcmp(name, "options") == 0)
Bram Moolenaard6e39182013-05-21 18:30:34 +02003415 return OptionsNew(SREQ_BUF, self->buf, (checkfun) CheckBuffer,
3416 (PyObject *) self);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003417 else if (strcmp(name, "__members__") == 0)
3418 return ObjectDir(NULL, BufferAttrs);
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003419 else
3420 return NULL;
3421}
3422
Bram Moolenaare9ba5162013-05-29 22:02:22 +02003423 static int
3424BufferSetattr(BufferObject *self, char *name, PyObject *valObject)
3425{
3426 if (CheckBuffer(self))
3427 return -1;
3428
3429 if (strcmp(name, "name") == 0)
3430 {
3431 char_u *val;
3432 aco_save_T aco;
3433 int r;
3434 PyObject *todecref;
3435
3436 if (!(val = StringToChars(valObject, &todecref)))
3437 return -1;
3438
3439 VimTryStart();
3440 /* Using aucmd_*: autocommands will be executed by rename_buffer */
3441 aucmd_prepbuf(&aco, self->buf);
3442 r = rename_buffer(val);
3443 aucmd_restbuf(&aco);
3444 Py_XDECREF(todecref);
3445 if (VimTryEnd())
3446 return -1;
3447
3448 if (r == FAIL)
3449 {
3450 PyErr_SetVim(_("failed to rename buffer"));
3451 return -1;
3452 }
3453 return 0;
3454 }
3455 else
3456 {
3457 PyErr_SetString(PyExc_AttributeError, name);
3458 return -1;
3459 }
3460}
3461
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003462 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003463BufferAppend(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003464{
Bram Moolenaard6e39182013-05-21 18:30:34 +02003465 return RBAppend(self, args, 1, -1, NULL);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003466}
3467
3468 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003469BufferMark(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003470{
3471 pos_T *posp;
3472 char *pmark;
3473 char mark;
Bram Moolenaar105bc352013-05-17 16:03:57 +02003474 buf_T *savebuf;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003475
Bram Moolenaard6e39182013-05-21 18:30:34 +02003476 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003477 return NULL;
3478
3479 if (!PyArg_ParseTuple(args, "s", &pmark))
3480 return NULL;
3481 mark = *pmark;
3482
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003483 VimTryStart();
Bram Moolenaard6e39182013-05-21 18:30:34 +02003484 switch_buffer(&savebuf, self->buf);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003485 posp = getmark(mark, FALSE);
Bram Moolenaar105bc352013-05-17 16:03:57 +02003486 restore_buffer(savebuf);
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003487 if (VimTryEnd())
3488 return NULL;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003489
3490 if (posp == NULL)
3491 {
3492 PyErr_SetVim(_("invalid mark name"));
3493 return NULL;
3494 }
3495
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003496 if (posp->lnum <= 0)
3497 {
3498 /* Or raise an error? */
3499 Py_INCREF(Py_None);
3500 return Py_None;
3501 }
3502
3503 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
3504}
3505
3506 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003507BufferRange(BufferObject *self, PyObject *args)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003508{
3509 PyInt start;
3510 PyInt end;
3511
Bram Moolenaard6e39182013-05-21 18:30:34 +02003512 if (CheckBuffer(self))
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003513 return NULL;
3514
3515 if (!PyArg_ParseTuple(args, "nn", &start, &end))
3516 return NULL;
3517
Bram Moolenaard6e39182013-05-21 18:30:34 +02003518 return RangeNew(self->buf, start, end);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003519}
3520
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003521 static PyObject *
Bram Moolenaard6e39182013-05-21 18:30:34 +02003522BufferRepr(BufferObject *self)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003523{
3524 static char repr[100];
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003525
Bram Moolenaard6e39182013-05-21 18:30:34 +02003526 if (self->buf == INVALID_BUFFER_VALUE)
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003527 {
3528 vim_snprintf(repr, 100, _("<buffer object (deleted) at %p>"), (self));
3529 return PyString_FromString(repr);
3530 }
3531 else
3532 {
Bram Moolenaard6e39182013-05-21 18:30:34 +02003533 char *name = (char *)self->buf->b_fname;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003534 PyInt len;
3535
3536 if (name == NULL)
3537 name = "";
3538 len = strlen(name);
3539
3540 if (len > 35)
3541 name = name + (35 - len);
3542
3543 vim_snprintf(repr, 100, "<buffer %s%s>", len > 35 ? "..." : "", name);
3544
3545 return PyString_FromString(repr);
3546 }
3547}
3548
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003549static struct PyMethodDef BufferMethods[] = {
Bram Moolenaar182dc4f2013-05-21 19:01:55 +02003550 /* name, function, calling, documentation */
3551 {"append", (PyCFunction)BufferAppend, METH_VARARGS, "Append data to Vim buffer" },
3552 {"mark", (PyCFunction)BufferMark, METH_VARARGS, "Return (row,col) representing position of named mark" },
3553 {"range", (PyCFunction)BufferRange, METH_VARARGS, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003554 {"__dir__", (PyCFunction)BufferDir, METH_NOARGS, ""},
3555 { NULL, NULL, 0, NULL}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003556};
3557
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003558/*
3559 * Buffer list object - Implementation
3560 */
3561
3562static PyTypeObject BufMapType;
3563
3564typedef struct
3565{
3566 PyObject_HEAD
3567} BufMapObject;
3568
3569 static PyInt
3570BufMapLength(PyObject *self UNUSED)
3571{
3572 buf_T *b = firstbuf;
3573 PyInt n = 0;
3574
3575 while (b)
3576 {
3577 ++n;
3578 b = b->b_next;
3579 }
3580
3581 return n;
3582}
3583
3584 static PyObject *
3585BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
3586{
3587 buf_T *b;
3588 int bnr;
3589
3590#if PY_MAJOR_VERSION < 3
3591 if (PyInt_Check(keyObject))
3592 bnr = PyInt_AsLong(keyObject);
3593 else
3594#endif
3595 if (PyLong_Check(keyObject))
3596 bnr = PyLong_AsLong(keyObject);
3597 else
3598 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02003599 PyErr_SetString(PyExc_TypeError, _("key must be integer"));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003600 return NULL;
3601 }
3602
3603 b = buflist_findnr(bnr);
3604
3605 if (b)
3606 return BufferNew(b);
3607 else
3608 {
Bram Moolenaar4d188da2013-05-15 15:35:09 +02003609 PyErr_SetObject(PyExc_KeyError, keyObject);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003610 return NULL;
3611 }
3612}
3613
3614 static void
3615BufMapIterDestruct(PyObject *buffer)
3616{
3617 /* Iteration was stopped before all buffers were processed */
3618 if (buffer)
3619 {
3620 Py_DECREF(buffer);
3621 }
3622}
3623
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003624 static int
3625BufMapIterTraverse(PyObject *buffer, visitproc visit, void *arg)
3626{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003627 if (buffer)
3628 Py_VISIT(buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003629 return 0;
3630}
3631
3632 static int
3633BufMapIterClear(PyObject **buffer)
3634{
Bram Moolenaar774267b2013-05-21 20:51:59 +02003635 if (*buffer)
3636 Py_CLEAR(*buffer);
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003637 return 0;
3638}
3639
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003640 static PyObject *
3641BufMapIterNext(PyObject **buffer)
3642{
3643 PyObject *next;
3644 PyObject *r;
3645
3646 if (!*buffer)
3647 return NULL;
3648
3649 r = *buffer;
3650
3651 if (CheckBuffer((BufferObject *)(r)))
3652 {
3653 *buffer = NULL;
3654 return NULL;
3655 }
3656
3657 if (!((BufferObject *)(r))->buf->b_next)
3658 next = NULL;
3659 else if (!(next = BufferNew(((BufferObject *)(r))->buf->b_next)))
3660 return NULL;
3661 *buffer = next;
Bram Moolenaar9e74e302013-05-17 21:20:17 +02003662 /* Do not increment reference: we no longer hold it (decref), but whoever
3663 * on other side will hold (incref). Decref+incref = nothing. */
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003664 return r;
3665}
3666
3667 static PyObject *
3668BufMapIter(PyObject *self UNUSED)
3669{
3670 PyObject *buffer;
3671
3672 buffer = BufferNew(firstbuf);
3673 return IterNew(buffer,
Bram Moolenaarcfef5ff2013-05-17 16:24:32 +02003674 (destructorfun) BufMapIterDestruct, (nextfun) BufMapIterNext,
3675 (traversefun) BufMapIterTraverse, (clearfun) BufMapIterClear);
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02003676}
3677
3678static PyMappingMethods BufMapAsMapping = {
3679 (lenfunc) BufMapLength,
3680 (binaryfunc) BufMapItem,
3681 (objobjargproc) 0,
3682};
3683
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02003684/* Current items object
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02003685 */
3686
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003687static char *CurrentAttrs[] = {
3688 "buffer", "window", "line", "range", "tabpage",
3689 NULL
3690};
3691
3692 static PyObject *
3693CurrentDir(PyObject *self)
3694{
3695 return ObjectDir(self, CurrentAttrs);
3696}
3697
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003698 static PyObject *
3699CurrentGetattr(PyObject *self UNUSED, char *name)
3700{
3701 if (strcmp(name, "buffer") == 0)
3702 return (PyObject *)BufferNew(curbuf);
3703 else if (strcmp(name, "window") == 0)
Bram Moolenaarcabf80f2013-05-17 16:18:33 +02003704 return (PyObject *)WindowNew(curwin, curtab);
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02003705 else if (strcmp(name, "tabpage") == 0)
3706 return (PyObject *)TabPageNew(curtab);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003707 else if (strcmp(name, "line") == 0)
3708 return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
3709 else if (strcmp(name, "range") == 0)
3710 return RangeNew(curbuf, RangeStart, RangeEnd);
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003711 else if (strcmp(name, "__members__") == 0)
3712 return ObjectDir(NULL, CurrentAttrs);
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003713 else
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003714#if PY_MAJOR_VERSION < 3
3715 return Py_FindMethod(WindowMethods, self, name);
3716#else
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003717 return NULL;
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003718#endif
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003719}
3720
3721 static int
3722CurrentSetattr(PyObject *self UNUSED, char *name, PyObject *value)
3723{
3724 if (strcmp(name, "line") == 0)
3725 {
3726 if (SetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum, value, NULL) == FAIL)
3727 return -1;
3728
3729 return 0;
3730 }
Bram Moolenaare7614592013-05-15 15:51:08 +02003731 else if (strcmp(name, "buffer") == 0)
3732 {
3733 int count;
3734
3735 if (value->ob_type != &BufferType)
3736 {
3737 PyErr_SetString(PyExc_TypeError, _("expected vim.buffer object"));
3738 return -1;
3739 }
3740
3741 if (CheckBuffer((BufferObject *)(value)))
3742 return -1;
3743 count = ((BufferObject *)(value))->buf->b_fnum;
3744
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003745 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003746 if (do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, count, 0) == FAIL)
3747 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003748 if (VimTryEnd())
3749 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003750 PyErr_SetVim(_("failed to switch to given buffer"));
3751 return -1;
3752 }
3753
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003754 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003755 }
3756 else if (strcmp(name, "window") == 0)
3757 {
3758 int count;
3759
3760 if (value->ob_type != &WindowType)
3761 {
3762 PyErr_SetString(PyExc_TypeError, _("expected vim.window object"));
3763 return -1;
3764 }
3765
3766 if (CheckWindow((WindowObject *)(value)))
3767 return -1;
3768 count = get_win_number(((WindowObject *)(value))->win, firstwin);
3769
3770 if (!count)
3771 {
3772 PyErr_SetString(PyExc_ValueError,
3773 _("failed to find window in the current tab page"));
3774 return -1;
3775 }
3776
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003777 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003778 win_goto(((WindowObject *)(value))->win);
3779 if (((WindowObject *)(value))->win != curwin)
3780 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003781 if (VimTryEnd())
3782 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003783 PyErr_SetString(PyExc_RuntimeError,
3784 _("did not switch to the specified window"));
3785 return -1;
3786 }
3787
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003788 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003789 }
3790 else if (strcmp(name, "tabpage") == 0)
3791 {
3792 if (value->ob_type != &TabPageType)
3793 {
3794 PyErr_SetString(PyExc_TypeError, _("expected vim.tabpage object"));
3795 return -1;
3796 }
3797
3798 if (CheckTabPage((TabPageObject *)(value)))
3799 return -1;
3800
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003801 VimTryStart();
Bram Moolenaare7614592013-05-15 15:51:08 +02003802 goto_tabpage_tp(((TabPageObject *)(value))->tab, TRUE, TRUE);
3803 if (((TabPageObject *)(value))->tab != curtab)
3804 {
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003805 if (VimTryEnd())
3806 return -1;
Bram Moolenaare7614592013-05-15 15:51:08 +02003807 PyErr_SetString(PyExc_RuntimeError,
3808 _("did not switch to the specified tab page"));
3809 return -1;
3810 }
3811
Bram Moolenaara7b64ce2013-05-21 20:40:40 +02003812 return VimTryEnd();
Bram Moolenaare7614592013-05-15 15:51:08 +02003813 }
Bram Moolenaar4d1da492013-04-24 13:39:15 +02003814 else
3815 {
3816 PyErr_SetString(PyExc_AttributeError, name);
3817 return -1;
3818 }
3819}
3820
Bram Moolenaardd8aca62013-05-29 22:36:10 +02003821static struct PyMethodDef CurrentMethods[] = {
3822 /* name, function, calling, documentation */
3823 {"__dir__", (PyCFunction)CurrentDir, METH_NOARGS, ""},
3824 { NULL, NULL, 0, NULL}
3825};
3826
Bram Moolenaardb913952012-06-29 12:54:53 +02003827 static void
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003828init_range_cmd(exarg_T *eap)
3829{
3830 RangeStart = eap->line1;
3831 RangeEnd = eap->line2;
3832}
3833
3834 static void
3835init_range_eval(typval_T *rettv UNUSED)
3836{
3837 RangeStart = (PyInt) curwin->w_cursor.lnum;
3838 RangeEnd = RangeStart;
3839}
3840
3841 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003842run_cmd(const char *cmd, void *arg UNUSED
3843#ifdef PY_CAN_RECURSE
3844 , PyGILState_STATE *pygilstate UNUSED
3845#endif
3846 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003847{
3848 PyRun_SimpleString((char *) cmd);
3849}
3850
3851static const char *code_hdr = "def " DOPY_FUNC "(line, linenr):\n ";
3852static int code_hdr_len = 30;
3853
3854 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003855run_do(const char *cmd, void *arg UNUSED
3856#ifdef PY_CAN_RECURSE
3857 , PyGILState_STATE *pygilstate
3858#endif
3859 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003860{
3861 PyInt lnum;
3862 size_t len;
3863 char *code;
3864 int status;
3865 PyObject *pyfunc, *pymain;
3866
Bram Moolenaar4ac66762013-05-28 22:31:46 +02003867 if (u_save((linenr_T)RangeStart - 1, (linenr_T)RangeEnd + 1) != OK)
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003868 {
3869 EMSG(_("cannot save undo information"));
3870 return;
3871 }
3872
3873 len = code_hdr_len + STRLEN(cmd);
3874 code = PyMem_New(char, len + 1);
3875 memcpy(code, code_hdr, code_hdr_len);
3876 STRCPY(code + code_hdr_len, cmd);
3877 status = PyRun_SimpleString(code);
3878 PyMem_Free(code);
3879
3880 if (status)
3881 {
3882 EMSG(_("failed to run the code"));
3883 return;
3884 }
3885
3886 status = 0;
3887 pymain = PyImport_AddModule("__main__");
3888 pyfunc = PyObject_GetAttrString(pymain, DOPY_FUNC);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003889#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003890 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003891#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003892
3893 for (lnum = RangeStart; lnum <= RangeEnd; ++lnum)
3894 {
3895 PyObject *line, *linenr, *ret;
3896
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003897#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003898 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003899#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003900 if (!(line = GetBufferLine(curbuf, lnum)))
3901 goto err;
3902 if (!(linenr = PyInt_FromLong((long) lnum)))
3903 {
3904 Py_DECREF(line);
3905 goto err;
3906 }
3907 ret = PyObject_CallFunctionObjArgs(pyfunc, line, linenr, NULL);
3908 Py_DECREF(line);
3909 Py_DECREF(linenr);
3910 if (!ret)
3911 goto err;
3912
3913 if (ret != Py_None)
3914 if (SetBufferLine(curbuf, lnum, ret, NULL) == FAIL)
3915 goto err;
3916
3917 Py_XDECREF(ret);
3918 PythonIO_Flush();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003919#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003920 PyGILState_Release(*pygilstate);
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003921#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003922 }
3923 goto out;
3924err:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003925#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003926 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003927#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003928 PyErr_PrintEx(0);
3929 PythonIO_Flush();
3930 status = 1;
3931out:
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003932#ifdef PY_CAN_RECURSE
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003933 if (!status)
3934 *pygilstate = PyGILState_Ensure();
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003935#endif
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003936 Py_DECREF(pyfunc);
3937 PyObject_SetAttrString(pymain, DOPY_FUNC, NULL);
3938 if (status)
3939 return;
3940 check_cursor();
3941 update_curbuf(NOT_VALID);
3942}
3943
3944 static void
Bram Moolenaar2a0f3d32013-05-21 22:23:56 +02003945run_eval(const char *cmd, typval_T *rettv
3946#ifdef PY_CAN_RECURSE
3947 , PyGILState_STATE *pygilstate UNUSED
3948#endif
3949 )
Bram Moolenaarb52f4c02013-05-21 18:19:38 +02003950{
3951 PyObject *r;
3952
3953 r = PyRun_String((char *) cmd, Py_eval_input, globals, globals);
3954 if (r == NULL)
3955 {
3956 if (PyErr_Occurred() && !msg_silent)
3957 PyErr_PrintEx(0);
3958 EMSG(_("E858: Eval did not return a valid python object"));
3959 }
3960 else
3961 {
3962 if (ConvertFromPyObject(r, rettv) == -1)
3963 EMSG(_("E859: Failed to convert returned python object to vim value"));
3964 Py_DECREF(r);
3965 }
3966 PyErr_Clear();
3967}
3968
3969 static void
Bram Moolenaardb913952012-06-29 12:54:53 +02003970set_ref_in_py(const int copyID)
3971{
3972 pylinkedlist_T *cur;
3973 dict_T *dd;
3974 list_T *ll;
3975
3976 if (lastdict != NULL)
3977 for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
3978 {
3979 dd = ((DictionaryObject *) (cur->pll_obj))->dict;
3980 if (dd->dv_copyID != copyID)
3981 {
3982 dd->dv_copyID = copyID;
3983 set_ref_in_ht(&dd->dv_hashtab, copyID);
3984 }
3985 }
3986
3987 if (lastlist != NULL)
3988 for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
3989 {
3990 ll = ((ListObject *) (cur->pll_obj))->list;
3991 if (ll->lv_copyID != copyID)
3992 {
3993 ll->lv_copyID = copyID;
3994 set_ref_in_list(ll, copyID);
3995 }
3996 }
3997}
3998
3999 static int
4000set_string_copy(char_u *str, typval_T *tv)
4001{
4002 tv->vval.v_string = vim_strsave(str);
4003 if (tv->vval.v_string == NULL)
4004 {
4005 PyErr_NoMemory();
4006 return -1;
4007 }
4008 return 0;
4009}
4010
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004011 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004012pydict_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004013{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004014 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004015 char_u *key;
4016 dictitem_T *di;
4017 PyObject *keyObject;
4018 PyObject *valObject;
4019 Py_ssize_t iter = 0;
4020
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004021 dict = dict_alloc();
4022 if (dict == NULL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004023 {
4024 PyErr_NoMemory();
4025 return -1;
4026 }
4027
4028 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004029 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004030
4031 while (PyDict_Next(obj, &iter, &keyObject, &valObject))
4032 {
4033 DICTKEY_DECL
4034
4035 if (keyObject == NULL)
4036 return -1;
4037 if (valObject == NULL)
4038 return -1;
4039
4040 DICTKEY_GET_NOTEMPTY(-1)
4041
4042 di = dictitem_alloc(key);
4043
4044 DICTKEY_UNREF
4045
4046 if (di == NULL)
4047 {
4048 PyErr_NoMemory();
4049 return -1;
4050 }
4051 di->di_tv.v_lock = 0;
4052
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004053 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004054 {
4055 vim_free(di);
4056 return -1;
4057 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004058
4059 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004060 {
4061 vim_free(di);
4062 PyErr_SetVim(_("failed to add key to dictionary"));
4063 return -1;
4064 }
4065 }
4066 return 0;
4067}
4068
4069 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004070pymap_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004071{
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004072 dict_T *dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004073 char_u *key;
4074 dictitem_T *di;
4075 PyObject *list;
4076 PyObject *litem;
4077 PyObject *keyObject;
4078 PyObject *valObject;
4079 Py_ssize_t lsize;
4080
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004081 dict = dict_alloc();
4082 if (dict == NULL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004083 {
4084 PyErr_NoMemory();
4085 return -1;
4086 }
4087
4088 tv->v_type = VAR_DICT;
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004089 tv->vval.v_dict = dict;
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004090
4091 list = PyMapping_Items(obj);
4092 if (list == NULL)
4093 return -1;
4094 lsize = PyList_Size(list);
4095 while (lsize--)
4096 {
4097 DICTKEY_DECL
4098
4099 litem = PyList_GetItem(list, lsize);
4100 if (litem == NULL)
4101 {
4102 Py_DECREF(list);
4103 return -1;
4104 }
4105
4106 keyObject = PyTuple_GetItem(litem, 0);
4107 if (keyObject == NULL)
4108 {
4109 Py_DECREF(list);
4110 Py_DECREF(litem);
4111 return -1;
4112 }
4113
4114 DICTKEY_GET_NOTEMPTY(-1)
4115
4116 valObject = PyTuple_GetItem(litem, 1);
4117 if (valObject == NULL)
4118 {
4119 Py_DECREF(list);
4120 Py_DECREF(litem);
4121 return -1;
4122 }
4123
4124 di = dictitem_alloc(key);
4125
4126 DICTKEY_UNREF
4127
4128 if (di == NULL)
4129 {
4130 Py_DECREF(list);
4131 Py_DECREF(litem);
4132 PyErr_NoMemory();
4133 return -1;
4134 }
4135 di->di_tv.v_lock = 0;
4136
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004137 if (_ConvertFromPyObject(valObject, &di->di_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004138 {
4139 vim_free(di);
4140 Py_DECREF(list);
4141 Py_DECREF(litem);
4142 return -1;
4143 }
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004144 if (dict_add(dict, di) == FAIL)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004145 {
4146 vim_free(di);
4147 Py_DECREF(list);
4148 Py_DECREF(litem);
4149 PyErr_SetVim(_("failed to add key to dictionary"));
4150 return -1;
4151 }
4152 Py_DECREF(litem);
4153 }
4154 Py_DECREF(list);
4155 return 0;
4156}
4157
4158 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004159pyseq_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004160{
4161 list_T *l;
4162
4163 l = list_alloc();
4164 if (l == NULL)
4165 {
4166 PyErr_NoMemory();
4167 return -1;
4168 }
4169
4170 tv->v_type = VAR_LIST;
4171 tv->vval.v_list = l;
4172
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004173 if (list_py_concat(l, obj, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004174 return -1;
4175
4176 return 0;
4177}
4178
4179 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004180pyiter_to_tv(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004181{
4182 PyObject *iterator = PyObject_GetIter(obj);
4183 PyObject *item;
4184 list_T *l;
4185 listitem_T *li;
4186
4187 l = list_alloc();
4188
4189 if (l == NULL)
4190 {
4191 PyErr_NoMemory();
4192 return -1;
4193 }
4194
4195 tv->vval.v_list = l;
4196 tv->v_type = VAR_LIST;
4197
4198
4199 if (iterator == NULL)
4200 return -1;
4201
4202 while ((item = PyIter_Next(obj)))
4203 {
4204 li = listitem_alloc();
4205 if (li == NULL)
4206 {
4207 PyErr_NoMemory();
4208 return -1;
4209 }
4210 li->li_tv.v_lock = 0;
4211
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004212 if (_ConvertFromPyObject(item, &li->li_tv, lookup_dict) == -1)
Bram Moolenaar3d0c52d2013-05-12 19:45:35 +02004213 return -1;
4214
4215 list_append(l, li);
4216
4217 Py_DECREF(item);
4218 }
4219
4220 Py_DECREF(iterator);
4221 return 0;
4222}
4223
Bram Moolenaardb913952012-06-29 12:54:53 +02004224typedef int (*pytotvfunc)(PyObject *, typval_T *, PyObject *);
4225
4226 static int
4227convert_dl(PyObject *obj, typval_T *tv,
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004228 pytotvfunc py_to_tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004229{
4230 PyObject *capsule;
4231 char hexBuf[sizeof(void *) * 2 + 3];
4232
4233 sprintf(hexBuf, "%p", obj);
4234
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004235# ifdef PY_USE_CAPSULE
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004236 capsule = PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004237# else
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004238 capsule = (PyObject *)PyDict_GetItemString(lookup_dict, hexBuf);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004239# endif
Bram Moolenaar221d6872012-06-30 13:34:34 +02004240 if (capsule == NULL)
Bram Moolenaardb913952012-06-29 12:54:53 +02004241 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004242# ifdef PY_USE_CAPSULE
Bram Moolenaardb913952012-06-29 12:54:53 +02004243 capsule = PyCapsule_New(tv, NULL, NULL);
Bram Moolenaar221d6872012-06-30 13:34:34 +02004244# else
4245 capsule = PyCObject_FromVoidPtr(tv, NULL);
4246# endif
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004247 PyDict_SetItemString(lookup_dict, hexBuf, capsule);
Bram Moolenaardb913952012-06-29 12:54:53 +02004248 Py_DECREF(capsule);
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004249 if (py_to_tv(obj, tv, lookup_dict) == -1)
Bram Moolenaardb913952012-06-29 12:54:53 +02004250 {
4251 tv->v_type = VAR_UNKNOWN;
4252 return -1;
4253 }
4254 /* As we are not using copy_tv which increments reference count we must
4255 * do it ourself. */
4256 switch(tv->v_type)
4257 {
4258 case VAR_DICT: ++tv->vval.v_dict->dv_refcount; break;
4259 case VAR_LIST: ++tv->vval.v_list->lv_refcount; break;
4260 }
4261 }
4262 else
4263 {
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004264 typval_T *v;
4265
4266# ifdef PY_USE_CAPSULE
4267 v = PyCapsule_GetPointer(capsule, NULL);
4268# else
Bram Moolenaar221d6872012-06-30 13:34:34 +02004269 v = PyCObject_AsVoidPtr(capsule);
Bram Moolenaar2afa3232012-06-29 16:28:28 +02004270# endif
Bram Moolenaardb913952012-06-29 12:54:53 +02004271 copy_tv(v, tv);
4272 }
4273 return 0;
4274}
4275
4276 static int
4277ConvertFromPyObject(PyObject *obj, typval_T *tv)
4278{
4279 PyObject *lookup_dict;
4280 int r;
4281
4282 lookup_dict = PyDict_New();
4283 r = _ConvertFromPyObject(obj, tv, lookup_dict);
4284 Py_DECREF(lookup_dict);
4285 return r;
4286}
4287
4288 static int
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004289_ConvertFromPyObject(PyObject *obj, typval_T *tv, PyObject *lookup_dict)
Bram Moolenaardb913952012-06-29 12:54:53 +02004290{
4291 if (obj->ob_type == &DictionaryType)
4292 {
4293 tv->v_type = VAR_DICT;
4294 tv->vval.v_dict = (((DictionaryObject *)(obj))->dict);
4295 ++tv->vval.v_dict->dv_refcount;
4296 }
4297 else if (obj->ob_type == &ListType)
4298 {
4299 tv->v_type = VAR_LIST;
4300 tv->vval.v_list = (((ListObject *)(obj))->list);
4301 ++tv->vval.v_list->lv_refcount;
4302 }
4303 else if (obj->ob_type == &FunctionType)
4304 {
4305 if (set_string_copy(((FunctionObject *) (obj))->name, tv) == -1)
4306 return -1;
4307
4308 tv->v_type = VAR_FUNC;
4309 func_ref(tv->vval.v_string);
4310 }
Bram Moolenaardb913952012-06-29 12:54:53 +02004311 else if (PyBytes_Check(obj))
4312 {
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004313 char_u *result;
Bram Moolenaardb913952012-06-29 12:54:53 +02004314
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004315 if (PyString_AsStringAndSize(obj, (char **) &result, NULL) == -1)
4316 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004317 if (result == NULL)
4318 return -1;
4319
4320 if (set_string_copy(result, tv) == -1)
4321 return -1;
4322
4323 tv->v_type = VAR_STRING;
4324 }
4325 else if (PyUnicode_Check(obj))
4326 {
4327 PyObject *bytes;
4328 char_u *result;
4329
Bram Moolenaardb913952012-06-29 12:54:53 +02004330 bytes = PyUnicode_AsEncodedString(obj, (char *)ENC_OPT, NULL);
4331 if (bytes == NULL)
4332 return -1;
4333
Bram Moolenaarafa6b9a2012-09-05 19:09:11 +02004334 if(PyString_AsStringAndSize(bytes, (char **) &result, NULL) == -1)
4335 return -1;
Bram Moolenaardb913952012-06-29 12:54:53 +02004336 if (result == NULL)
4337 return -1;
4338
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004339 if (set_string_copy(result, tv))
Bram Moolenaardb913952012-06-29 12:54:53 +02004340 {
4341 Py_XDECREF(bytes);
4342 return -1;
4343 }
4344 Py_XDECREF(bytes);
4345
4346 tv->v_type = VAR_STRING;
4347 }
Bram Moolenaar335e0b62013-04-24 13:47:45 +02004348#if PY_MAJOR_VERSION < 3
Bram Moolenaardb913952012-06-29 12:54:53 +02004349 else if (PyInt_Check(obj))
4350 {
4351 tv->v_type = VAR_NUMBER;
4352 tv->vval.v_number = (varnumber_T) PyInt_AsLong(obj);
4353 }
4354#endif
4355 else if (PyLong_Check(obj))
4356 {
4357 tv->v_type = VAR_NUMBER;
4358 tv->vval.v_number = (varnumber_T) PyLong_AsLong(obj);
4359 }
4360 else if (PyDict_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004361 return convert_dl(obj, tv, pydict_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004362#ifdef FEAT_FLOAT
4363 else if (PyFloat_Check(obj))
4364 {
4365 tv->v_type = VAR_FLOAT;
4366 tv->vval.v_float = (float_T) PyFloat_AsDouble(obj);
4367 }
4368#endif
4369 else if (PyIter_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004370 return convert_dl(obj, tv, pyiter_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004371 else if (PySequence_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004372 return convert_dl(obj, tv, pyseq_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004373 else if (PyMapping_Check(obj))
Bram Moolenaarb38caae2013-05-29 22:39:52 +02004374 return convert_dl(obj, tv, pymap_to_tv, lookup_dict);
Bram Moolenaardb913952012-06-29 12:54:53 +02004375 else
4376 {
Bram Moolenaar8661b172013-05-15 15:44:28 +02004377 PyErr_SetString(PyExc_TypeError,
4378 _("unable to convert to vim structure"));
Bram Moolenaardb913952012-06-29 12:54:53 +02004379 return -1;
4380 }
4381 return 0;
4382}
4383
4384 static PyObject *
4385ConvertToPyObject(typval_T *tv)
4386{
4387 if (tv == NULL)
4388 {
4389 PyErr_SetVim(_("NULL reference passed"));
4390 return NULL;
4391 }
4392 switch (tv->v_type)
4393 {
4394 case VAR_STRING:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004395 return PyBytes_FromString(tv->vval.v_string == NULL
4396 ? "" : (char *)tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004397 case VAR_NUMBER:
4398 return PyLong_FromLong((long) tv->vval.v_number);
4399#ifdef FEAT_FLOAT
4400 case VAR_FLOAT:
4401 return PyFloat_FromDouble((double) tv->vval.v_float);
4402#endif
4403 case VAR_LIST:
4404 return ListNew(tv->vval.v_list);
4405 case VAR_DICT:
4406 return DictionaryNew(tv->vval.v_dict);
4407 case VAR_FUNC:
Bram Moolenaard1f13fd2012-10-05 21:30:07 +02004408 return FunctionNew(tv->vval.v_string == NULL
4409 ? (char_u *)"" : tv->vval.v_string);
Bram Moolenaardb913952012-06-29 12:54:53 +02004410 case VAR_UNKNOWN:
4411 Py_INCREF(Py_None);
4412 return Py_None;
4413 default:
4414 PyErr_SetVim(_("internal error: invalid value type"));
4415 return NULL;
4416 }
4417}
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004418
4419typedef struct
4420{
4421 PyObject_HEAD
4422} CurrentObject;
4423static PyTypeObject CurrentType;
4424
4425 static void
4426init_structs(void)
4427{
4428 vim_memset(&OutputType, 0, sizeof(OutputType));
4429 OutputType.tp_name = "vim.message";
4430 OutputType.tp_basicsize = sizeof(OutputObject);
4431 OutputType.tp_flags = Py_TPFLAGS_DEFAULT;
4432 OutputType.tp_doc = "vim message object";
4433 OutputType.tp_methods = OutputMethods;
4434#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004435 OutputType.tp_getattro = (getattrofunc)OutputGetattro;
4436 OutputType.tp_setattro = (setattrofunc)OutputSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004437 OutputType.tp_alloc = call_PyType_GenericAlloc;
4438 OutputType.tp_new = call_PyType_GenericNew;
4439 OutputType.tp_free = call_PyObject_Free;
4440#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004441 OutputType.tp_getattr = (getattrfunc)OutputGetattr;
4442 OutputType.tp_setattr = (setattrfunc)OutputSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004443#endif
4444
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004445 vim_memset(&IterType, 0, sizeof(IterType));
4446 IterType.tp_name = "vim.iter";
4447 IterType.tp_basicsize = sizeof(IterObject);
4448 IterType.tp_flags = Py_TPFLAGS_DEFAULT;
4449 IterType.tp_doc = "generic iterator object";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004450 IterType.tp_iter = (getiterfunc)IterIter;
4451 IterType.tp_iternext = (iternextfunc)IterNext;
4452 IterType.tp_dealloc = (destructor)IterDestructor;
4453 IterType.tp_traverse = (traverseproc)IterTraverse;
4454 IterType.tp_clear = (inquiry)IterClear;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004455
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004456 vim_memset(&BufferType, 0, sizeof(BufferType));
4457 BufferType.tp_name = "vim.buffer";
4458 BufferType.tp_basicsize = sizeof(BufferType);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004459 BufferType.tp_dealloc = (destructor)BufferDestructor;
4460 BufferType.tp_repr = (reprfunc)BufferRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004461 BufferType.tp_as_sequence = &BufferAsSeq;
4462 BufferType.tp_as_mapping = &BufferAsMapping;
4463 BufferType.tp_flags = Py_TPFLAGS_DEFAULT;
4464 BufferType.tp_doc = "vim buffer object";
4465 BufferType.tp_methods = BufferMethods;
4466#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004467 BufferType.tp_getattro = (getattrofunc)BufferGetattro;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004468 BufferType.tp_setattro = (setattrofunc)BufferSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004469 BufferType.tp_alloc = call_PyType_GenericAlloc;
4470 BufferType.tp_new = call_PyType_GenericNew;
4471 BufferType.tp_free = call_PyObject_Free;
4472#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004473 BufferType.tp_getattr = (getattrfunc)BufferGetattr;
Bram Moolenaare9ba5162013-05-29 22:02:22 +02004474 BufferType.tp_setattr = (setattrfunc)BufferSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004475#endif
4476
4477 vim_memset(&WindowType, 0, sizeof(WindowType));
4478 WindowType.tp_name = "vim.window";
4479 WindowType.tp_basicsize = sizeof(WindowObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004480 WindowType.tp_dealloc = (destructor)WindowDestructor;
4481 WindowType.tp_repr = (reprfunc)WindowRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004482 WindowType.tp_flags = Py_TPFLAGS_DEFAULT;
4483 WindowType.tp_doc = "vim Window object";
4484 WindowType.tp_methods = WindowMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004485 WindowType.tp_traverse = (traverseproc)WindowTraverse;
4486 WindowType.tp_clear = (inquiry)WindowClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004487#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004488 WindowType.tp_getattro = (getattrofunc)WindowGetattro;
4489 WindowType.tp_setattro = (setattrofunc)WindowSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004490 WindowType.tp_alloc = call_PyType_GenericAlloc;
4491 WindowType.tp_new = call_PyType_GenericNew;
4492 WindowType.tp_free = call_PyObject_Free;
4493#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004494 WindowType.tp_getattr = (getattrfunc)WindowGetattr;
4495 WindowType.tp_setattr = (setattrfunc)WindowSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004496#endif
4497
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004498 vim_memset(&TabPageType, 0, sizeof(TabPageType));
4499 TabPageType.tp_name = "vim.tabpage";
4500 TabPageType.tp_basicsize = sizeof(TabPageObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004501 TabPageType.tp_dealloc = (destructor)TabPageDestructor;
4502 TabPageType.tp_repr = (reprfunc)TabPageRepr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004503 TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
4504 TabPageType.tp_doc = "vim tab page object";
4505 TabPageType.tp_methods = TabPageMethods;
4506#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004507 TabPageType.tp_getattro = (getattrofunc)TabPageGetattro;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004508 TabPageType.tp_alloc = call_PyType_GenericAlloc;
4509 TabPageType.tp_new = call_PyType_GenericNew;
4510 TabPageType.tp_free = call_PyObject_Free;
4511#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004512 TabPageType.tp_getattr = (getattrfunc)TabPageGetattr;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004513#endif
4514
Bram Moolenaardfa38d42013-05-15 13:38:47 +02004515 vim_memset(&BufMapType, 0, sizeof(BufMapType));
4516 BufMapType.tp_name = "vim.bufferlist";
4517 BufMapType.tp_basicsize = sizeof(BufMapObject);
4518 BufMapType.tp_as_mapping = &BufMapAsMapping;
4519 BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004520 BufMapType.tp_iter = BufMapIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004521 BufferType.tp_doc = "vim buffer list";
4522
4523 vim_memset(&WinListType, 0, sizeof(WinListType));
4524 WinListType.tp_name = "vim.windowlist";
4525 WinListType.tp_basicsize = sizeof(WinListType);
4526 WinListType.tp_as_sequence = &WinListAsSeq;
4527 WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
4528 WinListType.tp_doc = "vim window list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004529 WinListType.tp_dealloc = (destructor)WinListDestructor;
Bram Moolenaar5e538ec2013-05-15 15:12:29 +02004530
4531 vim_memset(&TabListType, 0, sizeof(TabListType));
4532 TabListType.tp_name = "vim.tabpagelist";
4533 TabListType.tp_basicsize = sizeof(TabListType);
4534 TabListType.tp_as_sequence = &TabListAsSeq;
4535 TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
4536 TabListType.tp_doc = "vim tab page list";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004537
4538 vim_memset(&RangeType, 0, sizeof(RangeType));
4539 RangeType.tp_name = "vim.range";
4540 RangeType.tp_basicsize = sizeof(RangeObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004541 RangeType.tp_dealloc = (destructor)RangeDestructor;
4542 RangeType.tp_repr = (reprfunc)RangeRepr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004543 RangeType.tp_as_sequence = &RangeAsSeq;
4544 RangeType.tp_as_mapping = &RangeAsMapping;
4545 RangeType.tp_flags = Py_TPFLAGS_DEFAULT;
4546 RangeType.tp_doc = "vim Range object";
4547 RangeType.tp_methods = RangeMethods;
Bram Moolenaar774267b2013-05-21 20:51:59 +02004548 RangeType.tp_traverse = (traverseproc)RangeTraverse;
4549 RangeType.tp_clear = (inquiry)RangeClear;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004550#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004551 RangeType.tp_getattro = (getattrofunc)RangeGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004552 RangeType.tp_alloc = call_PyType_GenericAlloc;
4553 RangeType.tp_new = call_PyType_GenericNew;
4554 RangeType.tp_free = call_PyObject_Free;
4555#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004556 RangeType.tp_getattr = (getattrfunc)RangeGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004557#endif
4558
4559 vim_memset(&CurrentType, 0, sizeof(CurrentType));
4560 CurrentType.tp_name = "vim.currentdata";
4561 CurrentType.tp_basicsize = sizeof(CurrentObject);
4562 CurrentType.tp_flags = Py_TPFLAGS_DEFAULT;
4563 CurrentType.tp_doc = "vim current object";
Bram Moolenaardd8aca62013-05-29 22:36:10 +02004564 CurrentType.tp_methods = CurrentMethods;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004565#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004566 CurrentType.tp_getattro = (getattrofunc)CurrentGetattro;
4567 CurrentType.tp_setattro = (setattrofunc)CurrentSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004568#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004569 CurrentType.tp_getattr = (getattrfunc)CurrentGetattr;
4570 CurrentType.tp_setattr = (setattrfunc)CurrentSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004571#endif
4572
4573 vim_memset(&DictionaryType, 0, sizeof(DictionaryType));
4574 DictionaryType.tp_name = "vim.dictionary";
4575 DictionaryType.tp_basicsize = sizeof(DictionaryObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004576 DictionaryType.tp_dealloc = (destructor)DictionaryDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004577 DictionaryType.tp_as_mapping = &DictionaryAsMapping;
4578 DictionaryType.tp_flags = Py_TPFLAGS_DEFAULT;
4579 DictionaryType.tp_doc = "dictionary pushing modifications to vim structure";
4580 DictionaryType.tp_methods = DictionaryMethods;
4581#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004582 DictionaryType.tp_getattro = (getattrofunc)DictionaryGetattro;
4583 DictionaryType.tp_setattro = (setattrofunc)DictionarySetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004584#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004585 DictionaryType.tp_getattr = (getattrfunc)DictionaryGetattr;
4586 DictionaryType.tp_setattr = (setattrfunc)DictionarySetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004587#endif
4588
4589 vim_memset(&ListType, 0, sizeof(ListType));
4590 ListType.tp_name = "vim.list";
Bram Moolenaard6e39182013-05-21 18:30:34 +02004591 ListType.tp_dealloc = (destructor)ListDestructor;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004592 ListType.tp_basicsize = sizeof(ListObject);
4593 ListType.tp_as_sequence = &ListAsSeq;
4594 ListType.tp_as_mapping = &ListAsMapping;
4595 ListType.tp_flags = Py_TPFLAGS_DEFAULT;
4596 ListType.tp_doc = "list pushing modifications to vim structure";
4597 ListType.tp_methods = ListMethods;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004598 ListType.tp_iter = (getiterfunc)ListIter;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004599#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004600 ListType.tp_getattro = (getattrofunc)ListGetattro;
4601 ListType.tp_setattro = (setattrofunc)ListSetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004602#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004603 ListType.tp_getattr = (getattrfunc)ListGetattr;
4604 ListType.tp_setattr = (setattrfunc)ListSetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004605#endif
4606
4607 vim_memset(&FunctionType, 0, sizeof(FunctionType));
Bram Moolenaarb6c589a2013-05-15 14:39:52 +02004608 FunctionType.tp_name = "vim.function";
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004609 FunctionType.tp_basicsize = sizeof(FunctionObject);
Bram Moolenaard6e39182013-05-21 18:30:34 +02004610 FunctionType.tp_dealloc = (destructor)FunctionDestructor;
4611 FunctionType.tp_call = (ternaryfunc)FunctionCall;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004612 FunctionType.tp_flags = Py_TPFLAGS_DEFAULT;
4613 FunctionType.tp_doc = "object that calls vim function";
4614 FunctionType.tp_methods = FunctionMethods;
4615#if PY_MAJOR_VERSION >= 3
Bram Moolenaard6e39182013-05-21 18:30:34 +02004616 FunctionType.tp_getattro = (getattrofunc)FunctionGetattro;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004617#else
Bram Moolenaard6e39182013-05-21 18:30:34 +02004618 FunctionType.tp_getattr = (getattrfunc)FunctionGetattr;
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004619#endif
4620
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004621 vim_memset(&OptionsType, 0, sizeof(OptionsType));
4622 OptionsType.tp_name = "vim.options";
4623 OptionsType.tp_basicsize = sizeof(OptionsObject);
4624 OptionsType.tp_flags = Py_TPFLAGS_DEFAULT;
4625 OptionsType.tp_doc = "object for manipulating options";
4626 OptionsType.tp_as_mapping = &OptionsAsMapping;
Bram Moolenaard6e39182013-05-21 18:30:34 +02004627 OptionsType.tp_dealloc = (destructor)OptionsDestructor;
4628 OptionsType.tp_traverse = (traverseproc)OptionsTraverse;
4629 OptionsType.tp_clear = (inquiry)OptionsClear;
Bram Moolenaar84e0f6c2013-05-06 03:52:55 +02004630
Bram Moolenaar4d1da492013-04-24 13:39:15 +02004631#if PY_MAJOR_VERSION >= 3
4632 vim_memset(&vimmodule, 0, sizeof(vimmodule));
4633 vimmodule.m_name = "vim";
4634 vimmodule.m_doc = "Vim Python interface\n";
4635 vimmodule.m_size = -1;
4636 vimmodule.m_methods = VimMethods;
4637#endif
4638}
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004639
4640#define PYTYPE_READY(type) \
4641 if (PyType_Ready(&type)) \
4642 return -1;
4643
4644 static int
4645init_types()
4646{
4647 PYTYPE_READY(IterType);
4648 PYTYPE_READY(BufferType);
4649 PYTYPE_READY(RangeType);
4650 PYTYPE_READY(WindowType);
4651 PYTYPE_READY(TabPageType);
4652 PYTYPE_READY(BufMapType);
4653 PYTYPE_READY(WinListType);
4654 PYTYPE_READY(TabListType);
4655 PYTYPE_READY(CurrentType);
4656 PYTYPE_READY(DictionaryType);
4657 PYTYPE_READY(ListType);
4658 PYTYPE_READY(FunctionType);
4659 PYTYPE_READY(OptionsType);
4660 PYTYPE_READY(OutputType);
4661 return 0;
4662}
4663
4664static BufMapObject TheBufferMap =
4665{
4666 PyObject_HEAD_INIT(&BufMapType)
4667};
4668
4669static WinListObject TheWindowList =
4670{
4671 PyObject_HEAD_INIT(&WinListType)
4672 NULL
4673};
4674
4675static CurrentObject TheCurrent =
4676{
4677 PyObject_HEAD_INIT(&CurrentType)
4678};
4679
4680static TabListObject TheTabPageList =
4681{
4682 PyObject_HEAD_INIT(&TabListType)
4683};
4684
4685static struct numeric_constant {
4686 char *name;
4687 int value;
4688} numeric_constants[] = {
4689 {"VAR_LOCKED", VAR_LOCKED},
4690 {"VAR_FIXED", VAR_FIXED},
4691 {"VAR_SCOPE", VAR_SCOPE},
4692 {"VAR_DEF_SCOPE", VAR_DEF_SCOPE},
4693};
4694
4695static struct object_constant {
4696 char *name;
4697 PyObject *value;
4698} object_constants[] = {
4699 {"buffers", (PyObject *)(void *)&TheBufferMap},
4700 {"windows", (PyObject *)(void *)&TheWindowList},
4701 {"tabpages", (PyObject *)(void *)&TheTabPageList},
4702 {"current", (PyObject *)(void *)&TheCurrent},
Bram Moolenaarcac867a2013-05-21 19:50:34 +02004703
4704 {"Buffer", (PyObject *)&BufferType},
4705 {"Range", (PyObject *)&RangeType},
4706 {"Window", (PyObject *)&WindowType},
4707 {"TabPage", (PyObject *)&TabPageType},
4708 {"Dictionary", (PyObject *)&DictionaryType},
4709 {"List", (PyObject *)&ListType},
4710 {"Function", (PyObject *)&FunctionType},
4711 {"Options", (PyObject *)&OptionsType},
Bram Moolenaar1dc28782013-05-21 19:11:01 +02004712};
4713
4714typedef int (*object_adder)(PyObject *, const char *, PyObject *);
4715
4716#define ADD_OBJECT(m, name, obj) \
4717 if (add_object(m, name, obj)) \
4718 return -1;
4719
4720#define ADD_CHECKED_OBJECT(m, name, obj) \
4721 { \
4722 PyObject *value = obj; \
4723 if (!value) \
4724 return -1; \
4725 ADD_OBJECT(m, name, value); \
4726 }
4727
4728 static int
4729populate_module(PyObject *m, object_adder add_object)
4730{
4731 int i;
4732
4733 for (i = 0; i < (int)(sizeof(numeric_constants)
4734 / sizeof(struct numeric_constant));
4735 ++i)
4736 ADD_CHECKED_OBJECT(m, numeric_constants[i].name,
4737 PyInt_FromLong(numeric_constants[i].value));
4738
4739 for (i = 0; i < (int)(sizeof(object_constants)
4740 / sizeof(struct object_constant));
4741 ++i)
4742 {
4743 PyObject *value;
4744
4745 value = object_constants[i].value;
4746 Py_INCREF(value);
4747 ADD_OBJECT(m, object_constants[i].name, value);
4748 }
4749
4750 if (!(VimError = PyErr_NewException("vim.error", NULL, NULL)))
4751 return -1;
4752 ADD_OBJECT(m, "error", VimError);
4753
4754 ADD_CHECKED_OBJECT(m, "vars", DictionaryNew(&globvardict));
4755 ADD_CHECKED_OBJECT(m, "vvars", DictionaryNew(&vimvardict));
4756 ADD_CHECKED_OBJECT(m, "options",
4757 OptionsNew(SREQ_GLOBAL, NULL, dummy_check, NULL));
4758 return 0;
4759}