blob: 10c614855b9acf58f54cc99dbcd18d85f13405a4 [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
15/*
16 * obtain a lock on the Vim data structures
17 */
18 static void
19Python_Lock_Vim(void)
20{
21}
22
23/*
24 * release a lock on the Vim data structures
25 */
26 static void
27Python_Release_Vim(void)
28{
29}
30
31/* Output object definition
32 */
33
34static PyObject *OutputWrite(PyObject *, PyObject *);
35static PyObject *OutputWritelines(PyObject *, PyObject *);
36
37typedef void (*writefn)(char_u *);
38static void writer(writefn fn, char_u *str, PyInt n);
39
40typedef struct
41{
42 PyObject_HEAD
43 long softspace;
44 long error;
45} OutputObject;
46
47static struct PyMethodDef OutputMethods[] = {
48 /* name, function, calling, documentation */
49 {"write", OutputWrite, 1, "" },
50 {"writelines", OutputWritelines, 1, "" },
51 { NULL, NULL, 0, NULL }
52};
53
Bram Moolenaarca8a4df2010-07-31 19:54:14 +020054#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
55
Bram Moolenaar170bf1a2010-07-24 23:51:45 +020056/*************/
57
58/* Output buffer management
59 */
60
61 static PyObject *
62OutputWrite(PyObject *self, PyObject *args)
63{
64 int len;
65 char *str;
66 int error = ((OutputObject *)(self))->error;
67
68 if (!PyArg_ParseTuple(args, "s#", &str, &len))
69 return NULL;
70
71 Py_BEGIN_ALLOW_THREADS
72 Python_Lock_Vim();
73 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
74 Python_Release_Vim();
75 Py_END_ALLOW_THREADS
76
77 Py_INCREF(Py_None);
78 return Py_None;
79}
80
81 static PyObject *
82OutputWritelines(PyObject *self, PyObject *args)
83{
84 PyInt n;
85 PyInt i;
86 PyObject *list;
87 int error = ((OutputObject *)(self))->error;
88
89 if (!PyArg_ParseTuple(args, "O", &list))
90 return NULL;
91 Py_INCREF(list);
92
93 if (!PyList_Check(list)) {
94 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
95 Py_DECREF(list);
96 return NULL;
97 }
98
99 n = PyList_Size(list);
100
101 for (i = 0; i < n; ++i)
102 {
103 PyObject *line = PyList_GetItem(list, i);
104 char *str;
105 PyInt len;
106
107 if (!PyArg_Parse(line, "s#", &str, &len)) {
108 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
109 Py_DECREF(list);
110 return NULL;
111 }
112
113 Py_BEGIN_ALLOW_THREADS
114 Python_Lock_Vim();
115 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
116 Python_Release_Vim();
117 Py_END_ALLOW_THREADS
118 }
119
120 Py_DECREF(list);
121 Py_INCREF(Py_None);
122 return Py_None;
123}
124
125static char_u *buffer = NULL;
126static PyInt buffer_len = 0;
127static PyInt buffer_size = 0;
128
129static writefn old_fn = NULL;
130
131 static void
132buffer_ensure(PyInt n)
133{
134 PyInt new_size;
135 char_u *new_buffer;
136
137 if (n < buffer_size)
138 return;
139
140 new_size = buffer_size;
141 while (new_size < n)
142 new_size += 80;
143
144 if (new_size != buffer_size)
145 {
146 new_buffer = alloc((unsigned)new_size);
147 if (new_buffer == NULL)
148 return;
149
150 if (buffer)
151 {
152 memcpy(new_buffer, buffer, buffer_len);
153 vim_free(buffer);
154 }
155
156 buffer = new_buffer;
157 buffer_size = new_size;
158 }
159}
160
161 static void
162PythonIO_Flush(void)
163{
164 if (old_fn && buffer_len)
165 {
166 buffer[buffer_len] = 0;
167 old_fn(buffer);
168 }
169
170 buffer_len = 0;
171}
172
173 static void
174writer(writefn fn, char_u *str, PyInt n)
175{
176 char_u *ptr;
177
178 if (fn != old_fn && old_fn != NULL)
179 PythonIO_Flush();
180
181 old_fn = fn;
182
183 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
184 {
185 PyInt len = ptr - str;
186
187 buffer_ensure(buffer_len + len + 1);
188
189 memcpy(buffer + buffer_len, str, len);
190 buffer_len += len;
191 buffer[buffer_len] = 0;
192 fn(buffer);
193 str = ptr + 1;
194 n -= len + 1;
195 buffer_len = 0;
196 }
197
198 /* Put the remaining text into the buffer for later printing */
199 buffer_ensure(buffer_len + n + 1);
200 memcpy(buffer + buffer_len, str, n);
201 buffer_len += n;
202}
203
204/***************/
205
206static PyTypeObject OutputType;
207
208static OutputObject Output =
209{
210 PyObject_HEAD_INIT(&OutputType)
211 0,
212 0
213};
214
215static OutputObject Error =
216{
217 PyObject_HEAD_INIT(&OutputType)
218 0,
219 1
220};
221
222 static int
223PythonIO_Init_io(void)
224{
225 PySys_SetObject("stdout", (PyObject *)(void *)&Output);
226 PySys_SetObject("stderr", (PyObject *)(void *)&Error);
227
228 if (PyErr_Occurred())
229 {
230 EMSG(_("E264: Python: Error initialising I/O objects"));
231 return -1;
232 }
233
234 return 0;
235}
236
237
238static PyObject *VimError;
239
240/* Check to see whether a Vim error has been reported, or a keyboard
241 * interrupt has been detected.
242 */
243 static int
244VimErrorCheck(void)
245{
246 if (got_int)
247 {
248 PyErr_SetNone(PyExc_KeyboardInterrupt);
249 return 1;
250 }
251 else if (did_emsg && !PyErr_Occurred())
252 {
253 PyErr_SetNone(VimError);
254 return 1;
255 }
256
257 return 0;
258}
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200259
260/* Vim module - Implementation
261 */
262 static PyObject *
263VimCommand(PyObject *self UNUSED, PyObject *args)
264{
265 char *cmd;
266 PyObject *result;
267
268 if (!PyArg_ParseTuple(args, "s", &cmd))
269 return NULL;
270
271 PyErr_Clear();
272
273 Py_BEGIN_ALLOW_THREADS
274 Python_Lock_Vim();
275
276 do_cmdline_cmd((char_u *)cmd);
277 update_screen(VALID);
278
279 Python_Release_Vim();
280 Py_END_ALLOW_THREADS
281
282 if (VimErrorCheck())
283 result = NULL;
284 else
285 result = Py_None;
286
287 Py_XINCREF(result);
288 return result;
289}
290
291#ifdef FEAT_EVAL
292/*
293 * Function to translate a typval_T into a PyObject; this will recursively
294 * translate lists/dictionaries into their Python equivalents.
295 *
296 * The depth parameter is to avoid infinite recursion, set it to 1 when
297 * you call VimToPython.
298 */
299 static PyObject *
300VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict)
301{
302 PyObject *result;
303 PyObject *newObj;
304 char ptrBuf[NUMBUFLEN];
305
306 /* Avoid infinite recursion */
307 if (depth > 100)
308 {
309 Py_INCREF(Py_None);
310 result = Py_None;
311 return result;
312 }
313
314 /* Check if we run into a recursive loop. The item must be in lookupDict
315 * then and we can use it again. */
316 if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL)
317 || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL))
318 {
319 sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U,
320 our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list
321 : (long_u)our_tv->vval.v_dict);
322 result = PyDict_GetItemString(lookupDict, ptrBuf);
323 if (result != NULL)
324 {
325 Py_INCREF(result);
326 return result;
327 }
328 }
329
330 if (our_tv->v_type == VAR_STRING)
331 {
332 result = Py_BuildValue("s", our_tv->vval.v_string);
333 }
334 else if (our_tv->v_type == VAR_NUMBER)
335 {
336 char buf[NUMBUFLEN];
337
338 /* For backwards compatibility numbers are stored as strings. */
339 sprintf(buf, "%ld", (long)our_tv->vval.v_number);
340 result = Py_BuildValue("s", buf);
341 }
342# ifdef FEAT_FLOAT
343 else if (our_tv->v_type == VAR_FLOAT)
344 {
345 char buf[NUMBUFLEN];
346
347 sprintf(buf, "%f", our_tv->vval.v_float);
348 result = Py_BuildValue("s", buf);
349 }
350# endif
351 else if (our_tv->v_type == VAR_LIST)
352 {
353 list_T *list = our_tv->vval.v_list;
354 listitem_T *curr;
355
356 result = PyList_New(0);
357
358 if (list != NULL)
359 {
360 PyDict_SetItemString(lookupDict, ptrBuf, result);
361
362 for (curr = list->lv_first; curr != NULL; curr = curr->li_next)
363 {
364 newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict);
365 PyList_Append(result, newObj);
366 Py_DECREF(newObj);
367 }
368 }
369 }
370 else if (our_tv->v_type == VAR_DICT)
371 {
372 result = PyDict_New();
373
374 if (our_tv->vval.v_dict != NULL)
375 {
376 hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab;
377 long_u todo = ht->ht_used;
378 hashitem_T *hi;
379 dictitem_T *di;
380
381 PyDict_SetItemString(lookupDict, ptrBuf, result);
382
383 for (hi = ht->ht_array; todo > 0; ++hi)
384 {
385 if (!HASHITEM_EMPTY(hi))
386 {
387 --todo;
388
389 di = dict_lookup(hi);
390 newObj = VimToPython(&di->di_tv, depth + 1, lookupDict);
391 PyDict_SetItemString(result, (char *)hi->hi_key, newObj);
392 Py_DECREF(newObj);
393 }
394 }
395 }
396 }
397 else
398 {
399 Py_INCREF(Py_None);
400 result = Py_None;
401 }
402
403 return result;
404}
405#endif
406
407 static PyObject *
Bram Moolenaar09092152010-08-08 16:38:42 +0200408VimEval(PyObject *self UNUSED, PyObject *args UNUSED)
Bram Moolenaarca8a4df2010-07-31 19:54:14 +0200409{
410#ifdef FEAT_EVAL
411 char *expr;
412 typval_T *our_tv;
413 PyObject *result;
414 PyObject *lookup_dict;
415
416 if (!PyArg_ParseTuple(args, "s", &expr))
417 return NULL;
418
419 Py_BEGIN_ALLOW_THREADS
420 Python_Lock_Vim();
421 our_tv = eval_expr((char_u *)expr, NULL);
422
423 Python_Release_Vim();
424 Py_END_ALLOW_THREADS
425
426 if (our_tv == NULL)
427 {
428 PyErr_SetVim(_("invalid expression"));
429 return NULL;
430 }
431
432 /* Convert the Vim type into a Python type. Create a dictionary that's
433 * used to check for recursive loops. */
434 lookup_dict = PyDict_New();
435 result = VimToPython(our_tv, 1, lookup_dict);
436 Py_DECREF(lookup_dict);
437
438
439 Py_BEGIN_ALLOW_THREADS
440 Python_Lock_Vim();
441 free_tv(our_tv);
442 Python_Release_Vim();
443 Py_END_ALLOW_THREADS
444
445 return result;
446#else
447 PyErr_SetVim(_("expressions disabled at compile time"));
448 return NULL;
449#endif
450}
451
452/*
453 * Vim module - Definitions
454 */
455
456static struct PyMethodDef VimMethods[] = {
457 /* name, function, calling, documentation */
458 {"command", VimCommand, 1, "Execute a Vim ex-mode command" },
459 {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" },
460 { NULL, NULL, 0, NULL }
461};
462
463typedef struct
464{
465 PyObject_HEAD
466 buf_T *buf;
467}
468BufferObject;
469
470#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
471
472/*
473 * Buffer list object - Implementation
474 */
475
476 static PyInt
477BufListLength(PyObject *self UNUSED)
478{
479 buf_T *b = firstbuf;
480 PyInt n = 0;
481
482 while (b)
483 {
484 ++n;
485 b = b->b_next;
486 }
487
488 return n;
489}
490
491 static PyObject *
492BufListItem(PyObject *self UNUSED, PyInt n)
493{
494 buf_T *b;
495
496 for (b = firstbuf; b; b = b->b_next, --n)
497 {
498 if (n == 0)
499 return BufferNew(b);
500 }
501
502 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
503 return NULL;
504}
505
506typedef struct
507{
508 PyObject_HEAD
509 win_T *win;
510} WindowObject;
511
512#define INVALID_WINDOW_VALUE ((win_T *)(-1))
513
514 static int
515CheckWindow(WindowObject *this)
516{
517 if (this->win == INVALID_WINDOW_VALUE)
518 {
519 PyErr_SetVim(_("attempt to refer to deleted window"));
520 return -1;
521 }
522
523 return 0;
524}
525
526static int WindowSetattr(PyObject *, char *, PyObject *);
527static PyObject *WindowRepr(PyObject *);
528
529 static int
530WindowSetattr(PyObject *self, char *name, PyObject *val)
531{
532 WindowObject *this = (WindowObject *)(self);
533
534 if (CheckWindow(this))
535 return -1;
536
537 if (strcmp(name, "buffer") == 0)
538 {
539 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
540 return -1;
541 }
542 else if (strcmp(name, "cursor") == 0)
543 {
544 long lnum;
545 long col;
546 long len;
547
548 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
549 return -1;
550
551 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
552 {
553 PyErr_SetVim(_("cursor position outside buffer"));
554 return -1;
555 }
556
557 /* Check for keyboard interrupts */
558 if (VimErrorCheck())
559 return -1;
560
561 /* When column is out of range silently correct it. */
562 len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE));
563 if (col > len)
564 col = len;
565
566 this->win->w_cursor.lnum = lnum;
567 this->win->w_cursor.col = col;
568#ifdef FEAT_VIRTUALEDIT
569 this->win->w_cursor.coladd = 0;
570#endif
571 update_screen(VALID);
572
573 return 0;
574 }
575 else if (strcmp(name, "height") == 0)
576 {
577 int height;
578 win_T *savewin;
579
580 if (!PyArg_Parse(val, "i", &height))
581 return -1;
582
583#ifdef FEAT_GUI
584 need_mouse_correct = TRUE;
585#endif
586 savewin = curwin;
587 curwin = this->win;
588 win_setheight(height);
589 curwin = savewin;
590
591 /* Check for keyboard interrupts */
592 if (VimErrorCheck())
593 return -1;
594
595 return 0;
596 }
597#ifdef FEAT_VERTSPLIT
598 else if (strcmp(name, "width") == 0)
599 {
600 int width;
601 win_T *savewin;
602
603 if (!PyArg_Parse(val, "i", &width))
604 return -1;
605
606#ifdef FEAT_GUI
607 need_mouse_correct = TRUE;
608#endif
609 savewin = curwin;
610 curwin = this->win;
611 win_setwidth(width);
612 curwin = savewin;
613
614 /* Check for keyboard interrupts */
615 if (VimErrorCheck())
616 return -1;
617
618 return 0;
619 }
620#endif
621 else
622 {
623 PyErr_SetString(PyExc_AttributeError, name);
624 return -1;
625 }
626}
627
628 static PyObject *
629WindowRepr(PyObject *self)
630{
631 static char repr[100];
632 WindowObject *this = (WindowObject *)(self);
633
634 if (this->win == INVALID_WINDOW_VALUE)
635 {
636 vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self));
637 return PyString_FromString(repr);
638 }
639 else
640 {
641 int i = 0;
642 win_T *w;
643
644 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
645 ++i;
646
647 if (w == NULL)
648 vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
649 (self));
650 else
651 vim_snprintf(repr, 100, _("<window %d>"), i);
652
653 return PyString_FromString(repr);
654 }
655}
656
657/*
658 * Window list object - Implementation
659 */
660 static PyInt
661WinListLength(PyObject *self UNUSED)
662{
663 win_T *w = firstwin;
664 PyInt n = 0;
665
666 while (w != NULL)
667 {
668 ++n;
669 w = W_NEXT(w);
670 }
671
672 return n;
673}
674
675 static PyObject *
676WinListItem(PyObject *self UNUSED, PyInt n)
677{
678 win_T *w;
679
680 for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
681 if (n == 0)
682 return WindowNew(w);
683
684 PyErr_SetString(PyExc_IndexError, _("no such window"));
685 return NULL;
686}
687
688/* Convert a Python string into a Vim line.
689 *
690 * The result is in allocated memory. All internal nulls are replaced by
691 * newline characters. It is an error for the string to contain newline
692 * characters.
693 *
694 * On errors, the Python exception data is set, and NULL is returned.
695 */
696 static char *
697StringToLine(PyObject *obj)
698{
699 const char *str;
700 char *save;
701 PyInt len;
702 PyInt i;
703 char *p;
704
705 if (obj == NULL || !PyString_Check(obj))
706 {
707 PyErr_BadArgument();
708 return NULL;
709 }
710
711 str = PyString_AsString(obj);
712 len = PyString_Size(obj);
713
714 /*
715 * Error checking: String must not contain newlines, as we
716 * are replacing a single line, and we must replace it with
717 * a single line.
718 * A trailing newline is removed, so that append(f.readlines()) works.
719 */
720 p = memchr(str, '\n', len);
721 if (p != NULL)
722 {
723 if (p == str + len - 1)
724 --len;
725 else
726 {
727 PyErr_SetVim(_("string cannot contain newlines"));
728 return NULL;
729 }
730 }
731
732 /* Create a copy of the string, with internal nulls replaced by
733 * newline characters, as is the vim convention.
734 */
735 save = (char *)alloc((unsigned)(len+1));
736 if (save == NULL)
737 {
738 PyErr_NoMemory();
739 return NULL;
740 }
741
742 for (i = 0; i < len; ++i)
743 {
744 if (str[i] == '\0')
745 save[i] = '\n';
746 else
747 save[i] = str[i];
748 }
749
750 save[i] = '\0';
751
752 return save;
753}
754
755/* Get a line from the specified buffer. The line number is
756 * in Vim format (1-based). The line is returned as a Python
757 * string object.
758 */
759 static PyObject *
760GetBufferLine(buf_T *buf, PyInt n)
761{
762 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
763}
764
765
766/* Get a list of lines from the specified buffer. The line numbers
767 * are in Vim format (1-based). The range is from lo up to, but not
768 * including, hi. The list is returned as a Python list of string objects.
769 */
770 static PyObject *
771GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi)
772{
773 PyInt i;
774 PyInt n = hi - lo;
775 PyObject *list = PyList_New(n);
776
777 if (list == NULL)
778 return NULL;
779
780 for (i = 0; i < n; ++i)
781 {
782 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
783
784 /* Error check - was the Python string creation OK? */
785 if (str == NULL)
786 {
787 Py_DECREF(list);
788 return NULL;
789 }
790
791 /* Set the list item */
792 if (PyList_SetItem(list, i, str))
793 {
794 Py_DECREF(str);
795 Py_DECREF(list);
796 return NULL;
797 }
798 }
799
800 /* The ownership of the Python list is passed to the caller (ie,
801 * the caller should Py_DECREF() the object when it is finished
802 * with it).
803 */
804
805 return list;
806}
807
808/*
809 * Check if deleting lines made the cursor position invalid.
810 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
811 * deleted).
812 */
813 static void
814py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
815{
816 if (curwin->w_cursor.lnum >= lo)
817 {
818 /* Adjust the cursor position if it's in/after the changed
819 * lines. */
820 if (curwin->w_cursor.lnum >= hi)
821 {
822 curwin->w_cursor.lnum += extra;
823 check_cursor_col();
824 }
825 else if (extra < 0)
826 {
827 curwin->w_cursor.lnum = lo;
828 check_cursor();
829 }
830 else
831 check_cursor_col();
832 changed_cline_bef_curs();
833 }
834 invalidate_botline();
835}
836
837/* Replace a line in the specified buffer. The line number is
838 * in Vim format (1-based). The replacement line is given as
839 * a Python string object. The object is checked for validity
840 * and correct format. Errors are returned as a value of FAIL.
841 * The return value is OK on success.
842 * If OK is returned and len_change is not NULL, *len_change
843 * is set to the change in the buffer length.
844 */
845 static int
846SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change)
847{
848 /* First of all, we check the thpe of the supplied Python object.
849 * There are three cases:
850 * 1. NULL, or None - this is a deletion.
851 * 2. A string - this is a replacement.
852 * 3. Anything else - this is an error.
853 */
854 if (line == Py_None || line == NULL)
855 {
856 buf_T *savebuf = curbuf;
857
858 PyErr_Clear();
859 curbuf = buf;
860
861 if (u_savedel((linenr_T)n, 1L) == FAIL)
862 PyErr_SetVim(_("cannot save undo information"));
863 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
864 PyErr_SetVim(_("cannot delete line"));
865 else
866 {
867 if (buf == curwin->w_buffer)
868 py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1);
869 deleted_lines_mark((linenr_T)n, 1L);
870 }
871
872 curbuf = savebuf;
873
874 if (PyErr_Occurred() || VimErrorCheck())
875 return FAIL;
876
877 if (len_change)
878 *len_change = -1;
879
880 return OK;
881 }
882 else if (PyString_Check(line))
883 {
884 char *save = StringToLine(line);
885 buf_T *savebuf = curbuf;
886
887 if (save == NULL)
888 return FAIL;
889
890 /* We do not need to free "save" if ml_replace() consumes it. */
891 PyErr_Clear();
892 curbuf = buf;
893
894 if (u_savesub((linenr_T)n) == FAIL)
895 {
896 PyErr_SetVim(_("cannot save undo information"));
897 vim_free(save);
898 }
899 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
900 {
901 PyErr_SetVim(_("cannot replace line"));
902 vim_free(save);
903 }
904 else
905 changed_bytes((linenr_T)n, 0);
906
907 curbuf = savebuf;
908
909 /* Check that the cursor is not beyond the end of the line now. */
910 if (buf == curwin->w_buffer)
911 check_cursor_col();
912
913 if (PyErr_Occurred() || VimErrorCheck())
914 return FAIL;
915
916 if (len_change)
917 *len_change = 0;
918
919 return OK;
920 }
921 else
922 {
923 PyErr_BadArgument();
924 return FAIL;
925 }
926}
927
928
929/* Insert a number of lines into the specified buffer after the specifed line.
930 * The line number is in Vim format (1-based). The lines to be inserted are
931 * given as a Python list of string objects or as a single string. The lines
932 * to be added are checked for validity and correct format. Errors are
933 * returned as a value of FAIL. The return value is OK on success.
934 * If OK is returned and len_change is not NULL, *len_change
935 * is set to the change in the buffer length.
936 */
937 static int
938InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change)
939{
940 /* First of all, we check the type of the supplied Python object.
941 * It must be a string or a list, or the call is in error.
942 */
943 if (PyString_Check(lines))
944 {
945 char *str = StringToLine(lines);
946 buf_T *savebuf;
947
948 if (str == NULL)
949 return FAIL;
950
951 savebuf = curbuf;
952
953 PyErr_Clear();
954 curbuf = buf;
955
956 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
957 PyErr_SetVim(_("cannot save undo information"));
958 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
959 PyErr_SetVim(_("cannot insert line"));
960 else
961 appended_lines_mark((linenr_T)n, 1L);
962
963 vim_free(str);
964 curbuf = savebuf;
965 update_screen(VALID);
966
967 if (PyErr_Occurred() || VimErrorCheck())
968 return FAIL;
969
970 if (len_change)
971 *len_change = 1;
972
973 return OK;
974 }
975 else if (PyList_Check(lines))
976 {
977 PyInt i;
978 PyInt size = PyList_Size(lines);
979 char **array;
980 buf_T *savebuf;
981
982 array = (char **)alloc((unsigned)(size * sizeof(char *)));
983 if (array == NULL)
984 {
985 PyErr_NoMemory();
986 return FAIL;
987 }
988
989 for (i = 0; i < size; ++i)
990 {
991 PyObject *line = PyList_GetItem(lines, i);
992 array[i] = StringToLine(line);
993
994 if (array[i] == NULL)
995 {
996 while (i)
997 vim_free(array[--i]);
998 vim_free(array);
999 return FAIL;
1000 }
1001 }
1002
1003 savebuf = curbuf;
1004
1005 PyErr_Clear();
1006 curbuf = buf;
1007
1008 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
1009 PyErr_SetVim(_("cannot save undo information"));
1010 else
1011 {
1012 for (i = 0; i < size; ++i)
1013 {
1014 if (ml_append((linenr_T)(n + i),
1015 (char_u *)array[i], 0, FALSE) == FAIL)
1016 {
1017 PyErr_SetVim(_("cannot insert line"));
1018
1019 /* Free the rest of the lines */
1020 while (i < size)
1021 vim_free(array[i++]);
1022
1023 break;
1024 }
1025 vim_free(array[i]);
1026 }
1027 if (i > 0)
1028 appended_lines_mark((linenr_T)n, (long)i);
1029 }
1030
1031 /* Free the array of lines. All of its contents have now
1032 * been freed.
1033 */
1034 vim_free(array);
1035
1036 curbuf = savebuf;
1037 update_screen(VALID);
1038
1039 if (PyErr_Occurred() || VimErrorCheck())
1040 return FAIL;
1041
1042 if (len_change)
1043 *len_change = size;
1044
1045 return OK;
1046 }
1047 else
1048 {
1049 PyErr_BadArgument();
1050 return FAIL;
1051 }
1052}
1053
1054/*
1055 * Common routines for buffers and line ranges
1056 * -------------------------------------------
1057 */
1058
1059 static int
1060CheckBuffer(BufferObject *this)
1061{
1062 if (this->buf == INVALID_BUFFER_VALUE)
1063 {
1064 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1065 return -1;
1066 }
1067
1068 return 0;
1069}
1070
1071 static PyObject *
1072RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end)
1073{
1074 if (CheckBuffer(self))
1075 return NULL;
1076
1077 if (n < 0 || n > end - start)
1078 {
1079 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1080 return NULL;
1081 }
1082
1083 return GetBufferLine(self->buf, n+start);
1084}
1085
1086 static PyObject *
1087RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end)
1088{
1089 PyInt size;
1090
1091 if (CheckBuffer(self))
1092 return NULL;
1093
1094 size = end - start + 1;
1095
1096 if (lo < 0)
1097 lo = 0;
1098 else if (lo > size)
1099 lo = size;
1100 if (hi < 0)
1101 hi = 0;
1102 if (hi < lo)
1103 hi = lo;
1104 else if (hi > size)
1105 hi = size;
1106
1107 return GetBufferLineList(self->buf, lo+start, hi+start);
1108}
1109
1110 static PyInt
1111RBAsItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end)
1112{
1113 PyInt len_change;
1114
1115 if (CheckBuffer(self))
1116 return -1;
1117
1118 if (n < 0 || n > end - start)
1119 {
1120 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1121 return -1;
1122 }
1123
1124 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1125 return -1;
1126
1127 if (new_end)
1128 *new_end = end + len_change;
1129
1130 return 0;
1131}
1132
1133
1134 static PyObject *
1135RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end)
1136{
1137 PyObject *lines;
1138 PyInt len_change;
1139 PyInt max;
1140 PyInt n;
1141
1142 if (CheckBuffer(self))
1143 return NULL;
1144
1145 max = n = end - start + 1;
1146
1147 if (!PyArg_ParseTuple(args, "O|n", &lines, &n))
1148 return NULL;
1149
1150 if (n < 0 || n > max)
1151 {
1152 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1153 return NULL;
1154 }
1155
1156 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1157 return NULL;
1158
1159 if (new_end)
1160 *new_end = end + len_change;
1161
1162 Py_INCREF(Py_None);
1163 return Py_None;
1164}
1165
1166
1167/* Buffer object - Definitions
1168 */
1169
1170typedef struct
1171{
1172 PyObject_HEAD
1173 BufferObject *buf;
1174 PyInt start;
1175 PyInt end;
1176} RangeObject;
1177
1178 static PyObject *
1179RangeNew(buf_T *buf, PyInt start, PyInt end)
1180{
1181 BufferObject *bufr;
1182 RangeObject *self;
1183 self = PyObject_NEW(RangeObject, &RangeType);
1184 if (self == NULL)
1185 return NULL;
1186
1187 bufr = (BufferObject *)BufferNew(buf);
1188 if (bufr == NULL)
1189 {
1190 Py_DECREF(self);
1191 return NULL;
1192 }
1193 Py_INCREF(bufr);
1194
1195 self->buf = bufr;
1196 self->start = start;
1197 self->end = end;
1198
1199 return (PyObject *)(self);
1200}
1201
1202 static PyObject *
1203BufferAppend(PyObject *self, PyObject *args)
1204{
1205 return RBAppend((BufferObject *)(self), args, 1,
1206 (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1207 NULL);
1208}
1209
1210 static PyObject *
1211BufferMark(PyObject *self, PyObject *args)
1212{
1213 pos_T *posp;
1214 char *pmark;
1215 char mark;
1216 buf_T *curbuf_save;
1217
1218 if (CheckBuffer((BufferObject *)(self)))
1219 return NULL;
1220
1221 if (!PyArg_ParseTuple(args, "s", &pmark))
1222 return NULL;
1223 mark = *pmark;
1224
1225 curbuf_save = curbuf;
1226 curbuf = ((BufferObject *)(self))->buf;
1227 posp = getmark(mark, FALSE);
1228 curbuf = curbuf_save;
1229
1230 if (posp == NULL)
1231 {
1232 PyErr_SetVim(_("invalid mark name"));
1233 return NULL;
1234 }
1235
1236 /* Ckeck for keyboard interrupt */
1237 if (VimErrorCheck())
1238 return NULL;
1239
1240 if (posp->lnum <= 0)
1241 {
1242 /* Or raise an error? */
1243 Py_INCREF(Py_None);
1244 return Py_None;
1245 }
1246
1247 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1248}
1249
1250 static PyObject *
1251BufferRange(PyObject *self, PyObject *args)
1252{
1253 PyInt start;
1254 PyInt end;
1255
1256 if (CheckBuffer((BufferObject *)(self)))
1257 return NULL;
1258
1259 if (!PyArg_ParseTuple(args, "nn", &start, &end))
1260 return NULL;
1261
1262 return RangeNew(((BufferObject *)(self))->buf, start, end);
1263}
1264
1265static struct PyMethodDef BufferMethods[] = {
1266 /* name, function, calling, documentation */
1267 {"append", BufferAppend, 1, "Append data to Vim buffer" },
1268 {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" },
1269 {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" },
1270 { NULL, NULL, 0, NULL }
1271};
1272
1273 static PyObject *
1274RangeAppend(PyObject *self, PyObject *args)
1275{
1276 return RBAppend(((RangeObject *)(self))->buf, args,
1277 ((RangeObject *)(self))->start,
1278 ((RangeObject *)(self))->end,
1279 &((RangeObject *)(self))->end);
1280}
1281
1282 static PyInt
1283RangeLength(PyObject *self)
1284{
1285 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1286 if (CheckBuffer(((RangeObject *)(self))->buf))
1287 return -1; /* ??? */
1288
1289 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1290}
1291
1292 static PyObject *
1293RangeItem(PyObject *self, PyInt n)
1294{
1295 return RBItem(((RangeObject *)(self))->buf, n,
1296 ((RangeObject *)(self))->start,
1297 ((RangeObject *)(self))->end);
1298}
1299
1300 static PyObject *
1301RangeRepr(PyObject *self)
1302{
1303 static char repr[100];
1304 RangeObject *this = (RangeObject *)(self);
1305
1306 if (this->buf->buf == INVALID_BUFFER_VALUE)
1307 {
1308 vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>",
1309 (self));
1310 return PyString_FromString(repr);
1311 }
1312 else
1313 {
1314 char *name = (char *)this->buf->buf->b_fname;
1315 int len;
1316
1317 if (name == NULL)
1318 name = "";
1319 len = (int)strlen(name);
1320
1321 if (len > 45)
1322 name = name + (45 - len);
1323
1324 vim_snprintf(repr, 100, "<range %s%s (%d:%d)>",
1325 len > 45 ? "..." : "", name,
1326 this->start, this->end);
1327
1328 return PyString_FromString(repr);
1329 }
1330}
1331
1332 static PyObject *
1333RangeSlice(PyObject *self, PyInt lo, PyInt hi)
1334{
1335 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1336 ((RangeObject *)(self))->start,
1337 ((RangeObject *)(self))->end);
1338}
1339
1340/*
1341 * Line range object - Definitions
1342 */
1343
1344static struct PyMethodDef RangeMethods[] = {
1345 /* name, function, calling, documentation */
1346 {"append", RangeAppend, 1, "Append data to the Vim range" },
1347 { NULL, NULL, 0, NULL }
1348};
1349