blob: cbfbaa76736f87ca4f8053c93898f810c69c85a2 [file] [log] [blame]
Bram Moolenaar170bf1a2010-07-24 23:51:45 +02001/* vi:set ts=8 sts=4 sw=4:
2 *
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/*
10 * Python extensions by Paul Moore, David Leonard, Roland Puntaier.
11 *
12 * Common code for if_python.c and if_python3.c.
13 */
14
Bram Moolenaar91805fc2011-06-26 04:01:44 +020015#ifdef FEAT_MBYTE
16# define ENC_OPT p_enc
17#else
18# define ENC_OPT "latin1"
19#endif
20
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020021/*
22 * obtain a lock on the Vim data structures
23 */
24 static void
25Python_Lock_Vim(void)
26{
27}
28
29/*
30 * release a lock on the Vim data structures
31 */
32 static void
33Python_Release_Vim(void)
34{
35}
36
37/* Output object definition
38 */
39
40static PyObject *OutputWrite(PyObject *, PyObject *);
41static PyObject *OutputWritelines(PyObject *, PyObject *);
Bram Moolenaara29a37d2011-03-22 15:47:44 +010042static PyObject *OutputFlush(PyObject *, PyObject *);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020043
Bram Moolenaar2eea1982010-09-21 16:49:37 +020044/* Function to write a line, points to either msg() or emsg(). */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020045typedef void (*writefn)(char_u *);
46static void writer(writefn fn, char_u *str, PyInt n);
47
48typedef struct
49{
50 PyObject_HEAD
51 long softspace;
52 long error;
53} OutputObject;
54
55static struct PyMethodDef OutputMethods[] = {
56 /* name, function, calling, documentation */
Bram Moolenaara29a37d2011-03-22 15:47:44 +010057 {"write", OutputWrite, 1, ""},
58 {"writelines", OutputWritelines, 1, ""},
59 {"flush", OutputFlush, 1, ""},
60 { NULL, NULL, 0, NULL}
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020061};
62
Bram Moolenaarca8a4df2010-07-31 19:54:14 +020063#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
64
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020065/*************/
66
67/* Output buffer management
68 */
69
70 static PyObject *
71OutputWrite(PyObject *self, PyObject *args)
72{
73 int len;
Bram Moolenaar19e60942011-06-19 00:27:51 +020074 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020075 int error = ((OutputObject *)(self))->error;
76
Bram Moolenaar27564802011-09-07 19:30:21 +020077 if (!PyArg_ParseTuple(args, "et#", ENC_OPT, &str, &len))
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020078 return NULL;
79
Bram Moolenaarb830f0c2012-04-20 13:31:21 +020080 /* TODO: This works around a gcc optimizer problem and avoids Vim
81 * from crashing. Should find a real solution. */
82 if (str == NULL)
83 return NULL;
84
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020085 Py_BEGIN_ALLOW_THREADS
86 Python_Lock_Vim();
87 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
88 Python_Release_Vim();
89 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +020090 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020091
92 Py_INCREF(Py_None);
93 return Py_None;
94}
95
96 static PyObject *
97OutputWritelines(PyObject *self, PyObject *args)
98{
99 PyInt n;
100 PyInt i;
101 PyObject *list;
102 int error = ((OutputObject *)(self))->error;
103
104 if (!PyArg_ParseTuple(args, "O", &list))
105 return NULL;
106 Py_INCREF(list);
107
108 if (!PyList_Check(list)) {
109 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
110 Py_DECREF(list);
111 return NULL;
112 }
113
114 n = PyList_Size(list);
115
116 for (i = 0; i < n; ++i)
117 {
118 PyObject *line = PyList_GetItem(list, i);
Bram Moolenaar19e60942011-06-19 00:27:51 +0200119 char *str = NULL;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200120 PyInt len;
121
Bram Moolenaar27564802011-09-07 19:30:21 +0200122 if (!PyArg_Parse(line, "et#", ENC_OPT, &str, &len)) {
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200123 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
124 Py_DECREF(list);
125 return NULL;
126 }
127
128 Py_BEGIN_ALLOW_THREADS
129 Python_Lock_Vim();
130 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
131 Python_Release_Vim();
132 Py_END_ALLOW_THREADS
Bram Moolenaar19e60942011-06-19 00:27:51 +0200133 PyMem_Free(str);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200134 }
135
136 Py_DECREF(list);
137 Py_INCREF(Py_None);
138 return Py_None;
139}
140
Bram Moolenaara29a37d2011-03-22 15:47:44 +0100141 static PyObject *
142OutputFlush(PyObject *self UNUSED, PyObject *args UNUSED)
143{
144 /* do nothing */
145 Py_INCREF(Py_None);
146 return Py_None;
147}
148
149
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200150/* Buffer IO, we write one whole line at a time. */
151static garray_T io_ga = {0, 0, 1, 80, NULL};
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200152static writefn old_fn = NULL;
153
154 static void
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200155PythonIO_Flush(void)
156{
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200157 if (old_fn != NULL && io_ga.ga_len > 0)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200158 {
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200159 ((char_u *)io_ga.ga_data)[io_ga.ga_len] = NUL;
160 old_fn((char_u *)io_ga.ga_data);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200161 }
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200162 io_ga.ga_len = 0;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200163}
164
165 static void
166writer(writefn fn, char_u *str, PyInt n)
167{
168 char_u *ptr;
169
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200170 /* Flush when switching output function. */
171 if (fn != old_fn)
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200172 PythonIO_Flush();
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200173 old_fn = fn;
174
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200175 /* Write each NL separated line. Text after the last NL is kept for
176 * writing later. */
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200177 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
178 {
179 PyInt len = ptr - str;
180
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200181 if (ga_grow(&io_ga, (int)(len + 1)) == FAIL)
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200182 break;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200183
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200184 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)len);
185 ((char *)io_ga.ga_data)[io_ga.ga_len + len] = NUL;
186 fn((char_u *)io_ga.ga_data);
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200187 str = ptr + 1;
188 n -= len + 1;
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200189 io_ga.ga_len = 0;
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200190 }
191
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200192 /* Put the remaining text into io_ga for later printing. */
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200193 if (n > 0 && ga_grow(&io_ga, (int)(n + 1)) == OK)
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200194 {
195 mch_memmove(((char *)io_ga.ga_data) + io_ga.ga_len, str, (size_t)n);
Bram Moolenaar6b5ef062010-10-27 12:18:00 +0200196 io_ga.ga_len += (int)n;
Bram Moolenaar2eea1982010-09-21 16:49:37 +0200197 }
Bram Moolenaar170bf1a2010-07-24 23:51:45 +0200198}
199
200/***************/
201
202static PyTypeObject OutputType;
203
204static OutputObject Output =
205{
206 PyObject_HEAD_INIT(&OutputType)
207 0,
208 0
209};
210
211static OutputObject Error =
212{
213 PyObject_HEAD_INIT(&OutputType)
214 0,
215 1
216};
217
218 static int
219PythonIO_Init_io(void)
220{
221 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
222 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
223
224 if (PyErr_Occurred())
225 {
226 EMSG(_("E264: Python: Error initialising I/O objects"));
227 return -1;
228 }
229
230 return 0;
231}
232
233
234static PyObject *VimError;
235
236/* Check to see whether a Vim error has been reported, or a keyboard
237 * interrupt has been detected.
238 */
239 static int
240VimErrorCheck(void)
241{
242 if (got_int)
243 {
244 PyErr_SetNone(PyExc_KeyboardInterrupt);
245 return 1;
246 }
247 else if (did_emsg && !PyErr_Occurred())
248 {
249 PyErr_SetNone(VimError);
250 return 1;
251 }
252
253 return 0;
254}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200255
256/* Vim module - Implementation
257 */
258 static PyObject *
259VimCommand(PyObject *self UNUSED, PyObject *args)
260{
261 char *cmd;
262 PyObject *result;
263
264 if (!PyArg_ParseTuple(args, "s", &cmd))
265 return NULL;
266
267 PyErr_Clear();
268
269 Py_BEGIN_ALLOW_THREADS
270 Python_Lock_Vim();
271
272 do_cmdline_cmd((char_u *)cmd);
273 update_screen(VALID);
274
275 Python_Release_Vim();
276 Py_END_ALLOW_THREADS
277
278 if (VimErrorCheck())
279 result = NULL;
280 else
281 result = Py_None;
282
283 Py_XINCREF(result);
284 return result;
285}
286
287#ifdef FEAT_EVAL
288/*
289 * Function to translate a typval_T into a PyObject; this will recursively
290 * translate lists/dictionaries into their Python equivalents.
291 *
292 * The depth parameter is to avoid infinite recursion, set it to 1 when
293 * you call VimToPython.
294 */
295 static PyObject *
296VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
297{
298 PyObject *result;
299 PyObject *newObj;
300 char ptrBuf[NUMBUFLEN];
301
302 /* Avoid infinite recursion */
303 if (depth > 100)
304 {
305 Py_INCREF(Py_None);
306 result = Py_None;
307 return result;
308 }
309
310 /* Check if we run into a recursive loop. The item must be in lookupDict
311 * then and we can use it again. */
312 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
313 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
314 {
315 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
316 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
317 : (long_u)our_tv->vval.v_dict);
318 result = PyDict_GetItemString(lookupDict, ptrBuf);
319 if (result != NULL)
320 {
321 Py_INCREF(result);
322 return result;
323 }
324 }
325
326 if (our_tv->v_type == VAR_STRING)
327 {
328 result = Py_BuildValue("s", our_tv->vval.v_string);
329 }
330 else if (our_tv->v_type == VAR_NUMBER)
331 {
332 char buf[NUMBUFLEN];
333
334 /* For backwards compatibility numbers are stored as strings. */
335 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
336 result = Py_BuildValue("s", buf);
337 }
338# ifdef FEAT_FLOAT
339 else if (our_tv->v_type == VAR_FLOAT)
340 {
341 char buf[NUMBUFLEN];
342
343 sprintf(buf, "%f", our_tv->vval.v_float);
344 result = Py_BuildValue("s", buf);
345 }
346# endif
347 else if (our_tv->v_type == VAR_LIST)
348 {
349 list_T *list = our_tv->vval.v_list;
350 listitem_T *curr;
351
352 result = PyList_New(0);
353
354 if (list != NULL)
355 {
356 PyDict_SetItemString(lookupDict, ptrBuf, result);
357
358 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
359 {
360 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
361 PyList_Append(result, newObj);
362 Py_DECREF(newObj);
363 }
364 }
365 }
366 else if (our_tv->v_type == VAR_DICT)
367 {
368 result = PyDict_New();
369
370 if (our_tv->vval.v_dict != NULL)
371 {
372 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
373 long_u todo = ht->ht_used;
374 hashitem_T *hi;
375 dictitem_T *di;
376
377 PyDict_SetItemString(lookupDict, ptrBuf, result);
378
379 for (hi = ht->ht_array; todo > 0; ++hi)
380 {
381 if (!HASHITEM_EMPTY(hi))
382 {
383 --todo;
384
385 di = dict_lookup(hi);
386 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
387 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
388 Py_DECREF(newObj);
389 }
390 }
391 }
392 }
393 else
394 {
395 Py_INCREF(Py_None);
396 result = Py_None;
397 }
398
399 return result;
400}
401#endif
402
403 static PyObject *
Bram Moolenaar09092152010-08-08 16:38:42 +0200404VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200405{
406#ifdef FEAT_EVAL
407 char *expr;
408 typval_T *our_tv;
409 PyObject *result;
410 PyObject *lookup_dict;
411
412 if (!PyArg_ParseTuple(args, "s", &expr))
413 return NULL;
414
415 Py_BEGIN_ALLOW_THREADS
416 Python_Lock_Vim();
417 our_tv = eval_expr((char_u *)expr, NULL);
418
419 Python_Release_Vim();
420 Py_END_ALLOW_THREADS
421
422 if (our_tv == NULL)
423 {
424 PyErr_SetVim(_("invalid expression"));
425 return NULL;
426 }
427
428 /* Convert the Vim type into a Python type. Create a dictionary that's
429 * used to check for recursive loops. */
430 lookup_dict = PyDict_New();
431 result = VimToPython(our_tv, 1, lookup_dict);
432 Py_DECREF(lookup_dict);
433
434
435 Py_BEGIN_ALLOW_THREADS
436 Python_Lock_Vim();
437 free_tv(our_tv);
438 Python_Release_Vim();
439 Py_END_ALLOW_THREADS
440
441 return result;
442#else
443 PyErr_SetVim(_("expressions disabled at compile time"));
444 return NULL;
445#endif
446}
447
448/*
449 * Vim module - Definitions
450 */
451
452static struct PyMethodDef VimMethods[] = {
453 /* name, function, calling, documentation */
454 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
455 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
456 { NULL, NULL, 0, NULL }
457};
458
459typedef struct
460{
461 PyObject_HEAD
462 buf_T *buf;
463}
464BufferObject;
465
466#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
467
468/*
469 * Buffer list object - Implementation
470 */
471
472 static PyInt
473BufListLength(PyObject *self UNUSED)
474{
475 buf_T *b = firstbuf;
476 PyInt n = 0;
477
478 while (b)
479 {
480 ++n;
481 b = b->b_next;
482 }
483
484 return n;
485}
486
487 static PyObject *
488BufListItem(PyObject *self UNUSED, PyInt n)
489{
490 buf_T *b;
491
492 for (b = firstbuf; b; b = b->b_next, --n)
493 {
494 if (n == 0)
495 return BufferNew(b);
496 }
497
498 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
499 return NULL;
500}
501
502typedef struct
503{
504 PyObject_HEAD
505 win_T *win;
506} WindowObject;
507
508#define INVALID_WINDOW_VALUE ((win_T *)(-1))
509
510 static int
511CheckWindow(WindowObject *this)
512{
513 if (this->win == INVALID_WINDOW_VALUE)
514 {
515 PyErr_SetVim(_("attempt to refer to deleted window"));
516 return -1;
517 }
518
519 return 0;
520}
521
522static int WindowSetattr(PyObject *, char *, PyObject *);
523static PyObject *WindowRepr(PyObject *);
524
525 static int
526WindowSetattr(PyObject *self, char *name, PyObject *val)
527{
528 WindowObject *this = (WindowObject *)(self);
529
530 if (CheckWindow(this))
531 return -1;
532
533 if (strcmp(name, "buffer") == 0)
534 {
535 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
536 return -1;
537 }
538 else if (strcmp(name, "cursor") == 0)
539 {
540 long lnum;
541 long col;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200542
543 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
544 return -1;
545
546 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
547 {
548 PyErr_SetVim(_("cursor position outside buffer"));
549 return -1;
550 }
551
552 /* Check for keyboard interrupts */
553 if (VimErrorCheck())
554 return -1;
555
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200556 this->win->w_cursor.lnum = lnum;
557 this->win->w_cursor.col = col;
558#ifdef FEAT_VIRTUALEDIT
559 this->win->w_cursor.coladd = 0;
560#endif
Bram Moolenaar03a807a2011-07-07 15:08:58 +0200561 /* When column is out of range silently correct it. */
562 check_cursor_col_win(this->win);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200563
Bram Moolenaar03a807a2011-07-07 15:08:58 +0200564 update_screen(VALID);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200565 return 0;
566 }
567 else if (strcmp(name, "height") == 0)
568 {
569 int height;
570 win_T *savewin;
571
572 if (!PyArg_Parse(val, "i", &height))
573 return -1;
574
575#ifdef FEAT_GUI
576 need_mouse_correct = TRUE;
577#endif
578 savewin = curwin;
579 curwin = this->win;
580 win_setheight(height);
581 curwin = savewin;
582
583 /* Check for keyboard interrupts */
584 if (VimErrorCheck())
585 return -1;
586
587 return 0;
588 }
589#ifdef FEAT_VERTSPLIT
590 else if (strcmp(name, "width") == 0)
591 {
592 int width;
593 win_T *savewin;
594
595 if (!PyArg_Parse(val, "i", &width))
596 return -1;
597
598#ifdef FEAT_GUI
599 need_mouse_correct = TRUE;
600#endif
601 savewin = curwin;
602 curwin = this->win;
603 win_setwidth(width);
604 curwin = savewin;
605
606 /* Check for keyboard interrupts */
607 if (VimErrorCheck())
608 return -1;
609
610 return 0;
611 }
612#endif
613 else
614 {
615 PyErr_SetString(PyExc_AttributeError, name);
616 return -1;
617 }
618}
619
620 static PyObject *
621WindowRepr(PyObject *self)
622{
623 static char repr[100];
624 WindowObject *this = (WindowObject *)(self);
625
626 if (this->win == INVALID_WINDOW_VALUE)
627 {
628 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
629 return PyString_FromString(repr);
630 }
631 else
632 {
633 int i = 0;
634 win_T *w;
635
636 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
637 ++i;
638
639 if (w == NULL)
640 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
641 (self));
642 else
643 vim_snprintf(repr, 100, _("<window %d>"), i);
644
645 return PyString_FromString(repr);
646 }
647}
648
649/*
650 * Window list object - Implementation
651 */
652 static PyInt
653WinListLength(PyObject *self UNUSED)
654{
655 win_T *w = firstwin;
656 PyInt n = 0;
657
658 while (w != NULL)
659 {
660 ++n;
661 w = W_NEXT(w);
662 }
663
664 return n;
665}
666
667 static PyObject *
668WinListItem(PyObject *self UNUSED, PyInt n)
669{
670 win_T *w;
671
672 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
673 if (n == 0)
674 return WindowNew(w);
675
676 PyErr_SetString(PyExc_IndexError, _("no such window"));
677 return NULL;
678}
679
680/* Convert a Python string into a Vim line.
681 *
682 * The result is in allocated memory. All internal nulls are replaced by
683 * newline characters. It is an error for the string to contain newline
684 * characters.
685 *
686 * On errors, the Python exception data is set, and NULL is returned.
687 */
688 static char *
689StringToLine(PyObject *obj)
690{
691 const char *str;
692 char *save;
Bram Moolenaar19e60942011-06-19 00:27:51 +0200693 PyObject *bytes;
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200694 PyInt len;
695 PyInt i;
696 char *p;
697
698 if (obj == NULL || !PyString_Check(obj))
699 {
700 PyErr_BadArgument();
701 return NULL;
702 }
703
Bram Moolenaar19e60942011-06-19 00:27:51 +0200704 bytes = PyString_AsBytes(obj); /* for Python 2 this does nothing */
705 str = PyString_AsString(bytes);
706 len = PyString_Size(bytes);
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200707
708 /*
709 * Error checking: String must not contain newlines, as we
710 * are replacing a single line, and we must replace it with
711 * a single line.
712 * A trailing newline is removed, so that append(f.readlines()) works.
713 */
714 p = memchr(str, '\n', len);
715 if (p != NULL)
716 {
717 if (p == str + len - 1)
718 --len;
719 else
720 {
721 PyErr_SetVim(_("string cannot contain newlines"));
722 return NULL;
723 }
724 }
725
726 /* Create a copy of the string, with internal nulls replaced by
727 * newline characters, as is the vim convention.
728 */
729 save = (char *)alloc((unsigned)(len+1));
730 if (save == NULL)
731 {
732 PyErr_NoMemory();
733 return NULL;
734 }
735
736 for (i = 0; i < len; ++i)
737 {
738 if (str[i] == '\0')
739 save[i] = '\n';
740 else
741 save[i] = str[i];
742 }
743
744 save[i] = '\0';
Bram Moolenaar19e60942011-06-19 00:27:51 +0200745 PyString_FreeBytes(bytes); /* Python 2 does nothing here */
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200746
747 return save;
748}
749
750/* Get a line from the specified buffer. The line number is
751 * in Vim format (1-based). The line is returned as a Python
752 * string object.
753 */
754 static PyObject *
755GetBufferLine(buf_T *buf, PyInt n)
756{
757 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
758}
759
760
761/* Get a list of lines from the specified buffer. The line numbers
762 * are in Vim format (1-based). The range is from lo up to, but not
763 * including, hi. The list is returned as a Python list of string objects.
764 */
765 static PyObject *
766GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
767{
768 PyInt i;
769 PyInt n = hi - lo;
770 PyObject *list = PyList_New(n);
771
772 if (list == NULL)
773 return NULL;
774
775 for (i = 0; i < n; ++i)
776 {
777 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
778
779 /* Error check - was the Python string creation OK? */
780 if (str == NULL)
781 {
782 Py_DECREF(list);
783 return NULL;
784 }
785
786 /* Set the list item */
787 if (PyList_SetItem(list, i, str))
788 {
789 Py_DECREF(str);
790 Py_DECREF(list);
791 return NULL;
792 }
793 }
794
795 /* The ownership of the Python list is passed to the caller (ie,
796 * the caller should Py_DECREF() the object when it is finished
797 * with it).
798 */
799
800 return list;
801}
802
803/*
804 * Check if deleting lines made the cursor position invalid.
805 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
806 * deleted).
807 */
808 static void
809py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
810{
811 if (curwin->w_cursor.lnum >= lo)
812 {
813 /* Adjust the cursor position if it's in/after the changed
814 * lines. */
815 if (curwin->w_cursor.lnum >= hi)
816 {
817 curwin->w_cursor.lnum += extra;
818 check_cursor_col();
819 }
820 else if (extra < 0)
821 {
822 curwin->w_cursor.lnum = lo;
823 check_cursor();
824 }
825 else
826 check_cursor_col();
827 changed_cline_bef_curs();
828 }
829 invalidate_botline();
830}
831
Bram Moolenaar19e60942011-06-19 00:27:51 +0200832/*
833 * Replace a line in the specified buffer. The line number is
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200834 * in Vim format (1-based). The replacement line is given as
835 * a Python string object. The object is checked for validity
836 * and correct format. Errors are returned as a value of FAIL.
837 * The return value is OK on success.
838 * If OK is returned and len_change is not NULL, *len_change
839 * is set to the change in the buffer length.
840 */
841 static int
842SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
843{
844 /* First of all, we check the thpe of the supplied Python object.
845 * There are three cases:
846 * 1. NULL, or None - this is a deletion.
847 * 2. A string - this is a replacement.
848 * 3. Anything else - this is an error.
849 */
850 if (line == Py_None || line == NULL)
851 {
852 buf_T *savebuf = curbuf;
853
854 PyErr_Clear();
855 curbuf = buf;
856
857 if (u_savedel((linenr_T)n, 1L) == FAIL)
858 PyErr_SetVim(_("cannot save undo information"));
859 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
860 PyErr_SetVim(_("cannot delete line"));
861 else
862 {
863 if (buf == curwin->w_buffer)
864 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
865 deleted_lines_mark((linenr_T)n, 1L);
866 }
867
868 curbuf = savebuf;
869
870 if (PyErr_Occurred() || VimErrorCheck())
871 return FAIL;
872
873 if (len_change)
874 *len_change = -1;
875
876 return OK;
877 }
878 else if (PyString_Check(line))
879 {
880 char *save = StringToLine(line);
881 buf_T *savebuf = curbuf;
882
883 if (save == NULL)
884 return FAIL;
885
886 /* We do not need to free "save" if ml_replace() consumes it. */
887 PyErr_Clear();
888 curbuf = buf;
889
890 if (u_savesub((linenr_T)n) == FAIL)
891 {
892 PyErr_SetVim(_("cannot save undo information"));
893 vim_free(save);
894 }
895 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
896 {
897 PyErr_SetVim(_("cannot replace line"));
898 vim_free(save);
899 }
900 else
901 changed_bytes((linenr_T)n, 0);
902
903 curbuf = savebuf;
904
905 /* Check that the cursor is not beyond the end of the line now. */
906 if (buf == curwin->w_buffer)
907 check_cursor_col();
908
909 if (PyErr_Occurred() || VimErrorCheck())
910 return FAIL;
911
912 if (len_change)
913 *len_change = 0;
914
915 return OK;
916 }
917 else
918 {
919 PyErr_BadArgument();
920 return FAIL;
921 }
922}
923
Bram Moolenaar19e60942011-06-19 00:27:51 +0200924/* Replace a range of lines in the specified buffer. The line numbers are in
925 * Vim format (1-based). The range is from lo up to, but not including, hi.
926 * The replacement lines are given as a Python list of string objects. The
927 * list is checked for validity and correct format. Errors are returned as a
928 * value of FAIL. The return value is OK on success.
929 * If OK is returned and len_change is not NULL, *len_change
930 * is set to the change in the buffer length.
931 */
932 static int
933SetBufferLineList(buf_T *buf, PyInt lo, PyInt hi, PyObject *list, PyInt *len_change)
934{
935 /* First of all, we check the thpe of the supplied Python object.
936 * There are three cases:
937 * 1. NULL, or None - this is a deletion.
938 * 2. A list - this is a replacement.
939 * 3. Anything else - this is an error.
940 */
941 if (list == Py_None || list == NULL)
942 {
943 PyInt i;
944 PyInt n = (int)(hi - lo);
945 buf_T *savebuf = curbuf;
946
947 PyErr_Clear();
948 curbuf = buf;
949
950 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
951 PyErr_SetVim(_("cannot save undo information"));
952 else
953 {
954 for (i = 0; i < n; ++i)
955 {
956 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
957 {
958 PyErr_SetVim(_("cannot delete line"));
959 break;
960 }
961 }
962 if (buf == curwin->w_buffer)
963 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n);
964 deleted_lines_mark((linenr_T)lo, (long)i);
965 }
966
967 curbuf = savebuf;
968
969 if (PyErr_Occurred() || VimErrorCheck())
970 return FAIL;
971
972 if (len_change)
973 *len_change = -n;
974
975 return OK;
976 }
977 else if (PyList_Check(list))
978 {
979 PyInt i;
980 PyInt new_len = PyList_Size(list);
981 PyInt old_len = hi - lo;
982 PyInt extra = 0; /* lines added to text, can be negative */
983 char **array;
984 buf_T *savebuf;
985
986 if (new_len == 0) /* avoid allocating zero bytes */
987 array = NULL;
988 else
989 {
990 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
991 if (array == NULL)
992 {
993 PyErr_NoMemory();
994 return FAIL;
995 }
996 }
997
998 for (i = 0; i < new_len; ++i)
999 {
1000 PyObject *line = PyList_GetItem(list, i);
1001
1002 array[i] = StringToLine(line);
1003 if (array[i] == NULL)
1004 {
1005 while (i)
1006 vim_free(array[--i]);
1007 vim_free(array);
1008 return FAIL;
1009 }
1010 }
1011
1012 savebuf = curbuf;
1013
1014 PyErr_Clear();
1015 curbuf = buf;
1016
1017 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
1018 PyErr_SetVim(_("cannot save undo information"));
1019
1020 /* If the size of the range is reducing (ie, new_len < old_len) we
1021 * need to delete some old_len. We do this at the start, by
1022 * repeatedly deleting line "lo".
1023 */
1024 if (!PyErr_Occurred())
1025 {
1026 for (i = 0; i < old_len - new_len; ++i)
1027 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
1028 {
1029 PyErr_SetVim(_("cannot delete line"));
1030 break;
1031 }
1032 extra -= i;
1033 }
1034
1035 /* For as long as possible, replace the existing old_len with the
1036 * new old_len. This is a more efficient operation, as it requires
1037 * less memory allocation and freeing.
1038 */
1039 if (!PyErr_Occurred())
1040 {
1041 for (i = 0; i < old_len && i < new_len; ++i)
1042 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
1043 == FAIL)
1044 {
1045 PyErr_SetVim(_("cannot replace line"));
1046 break;
1047 }
1048 }
1049 else
1050 i = 0;
1051
1052 /* Now we may need to insert the remaining new old_len. If we do, we
1053 * must free the strings as we finish with them (we can't pass the
1054 * responsibility to vim in this case).
1055 */
1056 if (!PyErr_Occurred())
1057 {
1058 while (i < new_len)
1059 {
1060 if (ml_append((linenr_T)(lo + i - 1),
1061 (char_u *)array[i], 0, FALSE) == FAIL)
1062 {
1063 PyErr_SetVim(_("cannot insert line"));
1064 break;
1065 }
1066 vim_free(array[i]);
1067 ++i;
1068 ++extra;
1069 }
1070 }
1071
1072 /* Free any left-over old_len, as a result of an error */
1073 while (i < new_len)
1074 {
1075 vim_free(array[i]);
1076 ++i;
1077 }
1078
1079 /* Free the array of old_len. All of its contents have now
1080 * been dealt with (either freed, or the responsibility passed
1081 * to vim.
1082 */
1083 vim_free(array);
1084
1085 /* Adjust marks. Invalidate any which lie in the
1086 * changed range, and move any in the remainder of the buffer.
1087 */
1088 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
1089 (long)MAXLNUM, (long)extra);
1090 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
1091
1092 if (buf == curwin->w_buffer)
1093 py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra);
1094
1095 curbuf = savebuf;
1096
1097 if (PyErr_Occurred() || VimErrorCheck())
1098 return FAIL;
1099
1100 if (len_change)
1101 *len_change = new_len - old_len;
1102
1103 return OK;
1104 }
1105 else
1106 {
1107 PyErr_BadArgument();
1108 return FAIL;
1109 }
1110}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001111
1112/* Insert a number of lines into the specified buffer after the specifed line.
1113 * The line number is in Vim format (1-based). The lines to be inserted are
1114 * given as a Python list of string objects or as a single string. The lines
1115 * to be added are checked for validity and correct format. Errors are
1116 * returned as a value of FAIL. The return value is OK on success.
1117 * If OK is returned and len_change is not NULL, *len_change
1118 * is set to the change in the buffer length.
1119 */
1120 static int
1121InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
1122{
1123 /* First of all, we check the type of the supplied Python object.
1124 * It must be a string or a list, or the call is in error.
1125 */
1126 if (PyString_Check(lines))
1127 {
1128 char *str = StringToLine(lines);
1129 buf_T *savebuf;
1130
1131 if (str == NULL)
1132 return FAIL;
1133
1134 savebuf = curbuf;
1135
1136 PyErr_Clear();
1137 curbuf = buf;
1138
1139 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
1140 PyErr_SetVim(_("cannot save undo information"));
1141 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
1142 PyErr_SetVim(_("cannot insert line"));
1143 else
1144 appended_lines_mark((linenr_T)n, 1L);
1145
1146 vim_free(str);
1147 curbuf = savebuf;
1148 update_screen(VALID);
1149
1150 if (PyErr_Occurred() || VimErrorCheck())
1151 return FAIL;
1152
1153 if (len_change)
1154 *len_change = 1;
1155
1156 return OK;
1157 }
1158 else if (PyList_Check(lines))
1159 {
1160 PyInt i;
1161 PyInt size = PyList_Size(lines);
1162 char **array;
1163 buf_T *savebuf;
1164
1165 array = (char **)alloc((unsigned)(size * sizeof(char *)));
1166 if (array == NULL)
1167 {
1168 PyErr_NoMemory();
1169 return FAIL;
1170 }
1171
1172 for (i = 0; i < size; ++i)
1173 {
1174 PyObject *line = PyList_GetItem(lines, i);
1175 array[i] = StringToLine(line);
1176
1177 if (array[i] == NULL)
1178 {
1179 while (i)
1180 vim_free(array[--i]);
1181 vim_free(array);
1182 return FAIL;
1183 }
1184 }
1185
1186 savebuf = curbuf;
1187
1188 PyErr_Clear();
1189 curbuf = buf;
1190
1191 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
1192 PyErr_SetVim(_("cannot save undo information"));
1193 else
1194 {
1195 for (i = 0; i < size; ++i)
1196 {
1197 if (ml_append((linenr_T)(n + i),
1198 (char_u *)array[i], 0, FALSE) == FAIL)
1199 {
1200 PyErr_SetVim(_("cannot insert line"));
1201
1202 /* Free the rest of the lines */
1203 while (i < size)
1204 vim_free(array[i++]);
1205
1206 break;
1207 }
1208 vim_free(array[i]);
1209 }
1210 if (i > 0)
1211 appended_lines_mark((linenr_T)n, (long)i);
1212 }
1213
1214 /* Free the array of lines. All of its contents have now
1215 * been freed.
1216 */
1217 vim_free(array);
1218
1219 curbuf = savebuf;
1220 update_screen(VALID);
1221
1222 if (PyErr_Occurred() || VimErrorCheck())
1223 return FAIL;
1224
1225 if (len_change)
1226 *len_change = size;
1227
1228 return OK;
1229 }
1230 else
1231 {
1232 PyErr_BadArgument();
1233 return FAIL;
1234 }
1235}
1236
1237/*
1238 * Common routines for buffers and line ranges
1239 * -------------------------------------------
1240 */
1241
1242 static int
1243CheckBuffer(BufferObject *this)
1244{
1245 if (this->buf == INVALID_BUFFER_VALUE)
1246 {
1247 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1248 return -1;
1249 }
1250
1251 return 0;
1252}
1253
1254 static PyObject *
1255RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
1256{
1257 if (CheckBuffer(self))
1258 return NULL;
1259
1260 if (n < 0 || n > end - start)
1261 {
1262 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1263 return NULL;
1264 }
1265
1266 return GetBufferLine(self->buf, n+start);
1267}
1268
1269 static PyObject *
1270RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
1271{
1272 PyInt size;
1273
1274 if (CheckBuffer(self))
1275 return NULL;
1276
1277 size = end - start + 1;
1278
1279 if (lo < 0)
1280 lo = 0;
1281 else if (lo > size)
1282 lo = size;
1283 if (hi < 0)
1284 hi = 0;
1285 if (hi < lo)
1286 hi = lo;
1287 else if (hi > size)
1288 hi = size;
1289
1290 return GetBufferLineList(self->buf, lo+start, hi+start);
1291}
1292
1293 static PyInt
1294RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
1295{
1296 PyInt len_change;
1297
1298 if (CheckBuffer(self))
1299 return -1;
1300
1301 if (n < 0 || n > end - start)
1302 {
1303 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1304 return -1;
1305 }
1306
1307 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1308 return -1;
1309
1310 if (new_end)
1311 *new_end = end + len_change;
1312
1313 return 0;
1314}
1315
Bram Moolenaar19e60942011-06-19 00:27:51 +02001316 static PyInt
1317RBAsSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
1318{
1319 PyInt size;
1320 PyInt len_change;
1321
1322 /* Self must be a valid buffer */
1323 if (CheckBuffer(self))
1324 return -1;
1325
1326 /* Sort out the slice range */
1327 size = end - start + 1;
1328
1329 if (lo < 0)
1330 lo = 0;
1331 else if (lo > size)
1332 lo = size;
1333 if (hi < 0)
1334 hi = 0;
1335 if (hi < lo)
1336 hi = lo;
1337 else if (hi > size)
1338 hi = size;
1339
1340 if (SetBufferLineList(self->buf, lo + start, hi + start,
1341 val, &len_change) == FAIL)
1342 return -1;
1343
1344 if (new_end)
1345 *new_end = end + len_change;
1346
1347 return 0;
1348}
1349
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001350
1351 static PyObject *
1352RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
1353{
1354 PyObject *lines;
1355 PyInt len_change;
1356 PyInt max;
1357 PyInt n;
1358
1359 if (CheckBuffer(self))
1360 return NULL;
1361
1362 max = n = end - start + 1;
1363
1364 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
1365 return NULL;
1366
1367 if (n < 0 || n > max)
1368 {
1369 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1370 return NULL;
1371 }
1372
1373 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1374 return NULL;
1375
1376 if (new_end)
1377 *new_end = end + len_change;
1378
1379 Py_INCREF(Py_None);
1380 return Py_None;
1381}
1382
1383
1384/* Buffer object - Definitions
1385 */
1386
1387typedef struct
1388{
1389 PyObject_HEAD
1390 BufferObject *buf;
1391 PyInt start;
1392 PyInt end;
1393} RangeObject;
1394
1395 static PyObject *
1396RangeNew(buf_T *buf, PyInt start, PyInt end)
1397{
1398 BufferObject *bufr;
1399 RangeObject *self;
1400 self = PyObject_NEW(RangeObject, &RangeType);
1401 if (self == NULL)
1402 return NULL;
1403
1404 bufr = (BufferObject *)BufferNew(buf);
1405 if (bufr == NULL)
1406 {
1407 Py_DECREF(self);
1408 return NULL;
1409 }
1410 Py_INCREF(bufr);
1411
1412 self->buf = bufr;
1413 self->start = start;
1414 self->end = end;
1415
1416 return (PyObject *)(self);
1417}
1418
1419 static PyObject *
1420BufferAppend(PyObject *self, PyObject *args)
1421{
1422 return RBAppend((BufferObject *)(self), args, 1,
1423 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1424 NULL);
1425}
1426
1427 static PyObject *
1428BufferMark(PyObject *self, PyObject *args)
1429{
1430 pos_T *posp;
1431 char *pmark;
1432 char mark;
1433 buf_T *curbuf_save;
1434
1435 if (CheckBuffer((BufferObject *)(self)))
1436 return NULL;
1437
1438 if (!PyArg_ParseTuple(args, "s", &pmark))
1439 return NULL;
1440 mark = *pmark;
1441
1442 curbuf_save = curbuf;
1443 curbuf = ((BufferObject *)(self))->buf;
1444 posp = getmark(mark, FALSE);
1445 curbuf = curbuf_save;
1446
1447 if (posp == NULL)
1448 {
1449 PyErr_SetVim(_("invalid mark name"));
1450 return NULL;
1451 }
1452
1453 /* Ckeck for keyboard interrupt */
1454 if (VimErrorCheck())
1455 return NULL;
1456
1457 if (posp->lnum <= 0)
1458 {
1459 /* Or raise an error? */
1460 Py_INCREF(Py_None);
1461 return Py_None;
1462 }
1463
1464 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1465}
1466
1467 static PyObject *
1468BufferRange(PyObject *self, PyObject *args)
1469{
1470 PyInt start;
1471 PyInt end;
1472
1473 if (CheckBuffer((BufferObject *)(self)))
1474 return NULL;
1475
1476 if (!PyArg_ParseTuple(args, "nn", &start, &end))
1477 return NULL;
1478
1479 return RangeNew(((BufferObject *)(self))->buf, start, end);
1480}
1481
1482static struct PyMethodDef BufferMethods[] = {
1483 /* name, function, calling, documentation */
1484 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1485 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1486 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
Bram Moolenaar7f85d292012-02-04 20:17:26 +01001487#if PY_VERSION_HEX >= 0x03000000
1488 {"__dir__", BufferDir, 4, "List its attributes" },
1489#endif
Bram Moolenaarca8a4df2010-07-31 19:54:14 +02001490 { NULL, NULL, 0, NULL }
1491};
1492
1493 static PyObject *
1494RangeAppend(PyObject *self, PyObject *args)
1495{
1496 return RBAppend(((RangeObject *)(self))->buf, args,
1497 ((RangeObject *)(self))->start,
1498 ((RangeObject *)(self))->end,
1499 &((RangeObject *)(self))->end);
1500}
1501
1502 static PyInt
1503RangeLength(PyObject *self)
1504{
1505 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1506 if (CheckBuffer(((RangeObject *)(self))->buf))
1507 return -1; /* ??? */
1508
1509 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1510}
1511
1512 static PyObject *
1513RangeItem(PyObject *self, PyInt n)
1514{
1515 return RBItem(((RangeObject *)(self))->buf, n,
1516 ((RangeObject *)(self))->start,
1517 ((RangeObject *)(self))->end);
1518}
1519
1520 static PyObject *
1521RangeRepr(PyObject *self)
1522{
1523 static char repr[100];
1524 RangeObject *this = (RangeObject *)(self);
1525
1526 if (this->buf->buf == INVALID_BUFFER_VALUE)
1527 {
1528 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1529 (self));
1530 return PyString_FromString(repr);
1531 }
1532 else
1533 {
1534 char *name = (char *)this->buf->buf->b_fname;
1535 int len;
1536
1537 if (name == NULL)
1538 name = "";
1539 len = (int)strlen(name);
1540
1541 if (len > 45)
1542 name = name + (45 - len);
1543
1544 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1545 len > 45 ? "..." : "", name,
1546 this->start, this->end);
1547
1548 return PyString_FromString(repr);
1549 }
1550}
1551
1552 static PyObject *
1553RangeSlice(PyObject *self, PyInt lo, PyInt hi)
1554{
1555 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1556 ((RangeObject *)(self))->start,
1557 ((RangeObject *)(self))->end);
1558}
1559
1560/*
1561 * Line range object - Definitions
1562 */
1563
1564static struct PyMethodDef RangeMethods[] = {
1565 /* name, function, calling, documentation */
1566 {"append", RangeAppend, 1, "Append data to the Vim range" },
1567 { NULL, NULL, 0, NULL }
1568};
1569