blob: 21c4365203618bb307abd439db0348065dd5e1bc [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* 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.
11 * Changes for Unix by David Leonard.
12 *
13 * This consists of four parts:
14 * 1. Python interpreter main program
15 * 2. Python output stream: writes output via [e]msg().
16 * 3. Implementation of the Vim module for Python
17 * 4. Utility functions for handling the interface between Vim and Python.
18 */
19
20#include "vim.h"
21
22#include <stdio.h>
23#include <stdarg.h>
24#include <limits.h>
25
26/* Python.h defines _POSIX_THREADS itself (if needed) */
27#ifdef _POSIX_THREADS
28# undef _POSIX_THREADS
29#endif
30
31#if defined(_WIN32) && defined (HAVE_FCNTL_H)
32# undef HAVE_FCNTL_H
33#endif
34
35#ifdef _DEBUG
36# undef _DEBUG
37#endif
38
39#ifdef HAVE_STDARG_H
40# undef HAVE_STDARG_H /* Python's config.h defines it as well. */
41#endif
42
43#include <Python.h>
44#if defined(MACOS) && !defined(MACOS_X_UNIX)
45# include "macglue.h"
46# include <CodeFragments.h>
47#endif
48#undef main /* Defined in python.h - aargh */
49#undef HAVE_FCNTL_H /* Clash with os_win32.h */
50
51#if !defined(FEAT_PYTHON) && defined(PROTO)
52/* Use this to be able to generate prototypes without python being used. */
53# define PyObject int
54# define PyThreadState int
55# define PyTypeObject int
56struct PyMethodDef { int a; };
57# define PySequenceMethods int
58#endif
59
60/* Parser flags */
61#define single_input 256
62#define file_input 257
63#define eval_input 258
64
65#if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x020300F0
66 /* Python 2.3: can invoke ":python" recursively. */
67# define PY_CAN_RECURSE
68#endif
69
70#if defined(DYNAMIC_PYTHON) || defined(PROTO)
71# ifndef DYNAMIC_PYTHON
72# define HINSTANCE int /* for generating prototypes */
73# endif
74
75/*
76 * Wrapper defines
77 */
78# define PyArg_Parse dll_PyArg_Parse
79# define PyArg_ParseTuple dll_PyArg_ParseTuple
80# define PyDict_SetItemString dll_PyDict_SetItemString
81# define PyErr_BadArgument dll_PyErr_BadArgument
82# define PyErr_Clear dll_PyErr_Clear
83# define PyErr_NoMemory dll_PyErr_NoMemory
84# define PyErr_Occurred dll_PyErr_Occurred
85# define PyErr_SetNone dll_PyErr_SetNone
86# define PyErr_SetString dll_PyErr_SetString
87# define PyEval_InitThreads dll_PyEval_InitThreads
88# define PyEval_RestoreThread dll_PyEval_RestoreThread
89# define PyEval_SaveThread dll_PyEval_SaveThread
90# ifdef PY_CAN_RECURSE
91# define PyGILState_Ensure dll_PyGILState_Ensure
92# define PyGILState_Release dll_PyGILState_Release
93# endif
94# define PyInt_AsLong dll_PyInt_AsLong
95# define PyInt_FromLong dll_PyInt_FromLong
96# define PyInt_Type (*dll_PyInt_Type)
97# define PyList_GetItem dll_PyList_GetItem
98# define PyList_New dll_PyList_New
99# define PyList_SetItem dll_PyList_SetItem
100# define PyList_Size dll_PyList_Size
101# define PyList_Type (*dll_PyList_Type)
102# define PyImport_ImportModule dll_PyImport_ImportModule
103# define PyDict_GetItemString dll_PyDict_GetItemString
104# define PyModule_GetDict dll_PyModule_GetDict
105# define PyRun_SimpleString dll_PyRun_SimpleString
106# define PyString_AsString dll_PyString_AsString
107# define PyString_FromString dll_PyString_FromString
108# define PyString_FromStringAndSize dll_PyString_FromStringAndSize
109# define PyString_Size dll_PyString_Size
110# define PyString_Type (*dll_PyString_Type)
111# define PySys_SetObject dll_PySys_SetObject
112# define PySys_SetArgv dll_PySys_SetArgv
113# define PyType_Type (*dll_PyType_Type)
114# define Py_BuildValue dll_Py_BuildValue
115# define Py_FindMethod dll_Py_FindMethod
116# define Py_InitModule4 dll_Py_InitModule4
117# define Py_Initialize dll_Py_Initialize
118# define _PyObject_New dll__PyObject_New
119# define _Py_NoneStruct (*dll__Py_NoneStruct)
120# define PyObject_Init dll__PyObject_Init
121# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
122# define PyType_IsSubtype dll_PyType_IsSubtype
123# endif
124# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
125# define PyObject_Malloc dll_PyObject_Malloc
126# define PyObject_Free dll_PyObject_Free
127# endif
128
129/*
130 * Pointers for dynamic link
131 */
132static int(*dll_PyArg_Parse)(PyObject *, char *, ...);
133static int(*dll_PyArg_ParseTuple)(PyObject *, char *, ...);
134static int(*dll_PyDict_SetItemString)(PyObject *dp, char *key, PyObject *item);
135static int(*dll_PyErr_BadArgument)(void);
136static void(*dll_PyErr_Clear)(void);
137static PyObject*(*dll_PyErr_NoMemory)(void);
138static PyObject*(*dll_PyErr_Occurred)(void);
139static void(*dll_PyErr_SetNone)(PyObject *);
140static void(*dll_PyErr_SetString)(PyObject *, const char *);
141static void(*dll_PyEval_InitThreads)(void);
142static void(*dll_PyEval_RestoreThread)(PyThreadState *);
143static PyThreadState*(*dll_PyEval_SaveThread)(void);
144# ifdef PY_CAN_RECURSE
145static PyGILState_STATE (*dll_PyGILState_Ensure)(void);
146static void (*dll_PyGILState_Release)(PyGILState_STATE);
147#endif
148static long(*dll_PyInt_AsLong)(PyObject *);
149static PyObject*(*dll_PyInt_FromLong)(long);
150static PyTypeObject* dll_PyInt_Type;
151static PyObject*(*dll_PyList_GetItem)(PyObject *, int);
152static PyObject*(*dll_PyList_New)(int size);
153static int(*dll_PyList_SetItem)(PyObject *, int, PyObject *);
154static int(*dll_PyList_Size)(PyObject *);
155static PyTypeObject* dll_PyList_Type;
156static PyObject*(*dll_PyImport_ImportModule)(const char *);
157static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
158static PyObject*(*dll_PyModule_GetDict)(PyObject *);
159static int(*dll_PyRun_SimpleString)(char *);
160static char*(*dll_PyString_AsString)(PyObject *);
161static PyObject*(*dll_PyString_FromString)(const char *);
162static PyObject*(*dll_PyString_FromStringAndSize)(const char *, int);
163static int(*dll_PyString_Size)(PyObject *);
164static PyTypeObject* dll_PyString_Type;
165static int(*dll_PySys_SetObject)(char *, PyObject *);
166static int(*dll_PySys_SetArgv)(int, char **);
167static PyTypeObject* dll_PyType_Type;
168static PyObject*(*dll_Py_BuildValue)(char *, ...);
169static PyObject*(*dll_Py_FindMethod)(struct PyMethodDef[], PyObject *, char *);
170static PyObject*(*dll_Py_InitModule4)(char *, struct PyMethodDef *, char *, PyObject *, int);
171static void(*dll_Py_Initialize)(void);
172static PyObject*(*dll__PyObject_New)(PyTypeObject *, PyObject *);
173static PyObject*(*dll__PyObject_Init)(PyObject *, PyTypeObject *);
174static PyObject* dll__Py_NoneStruct;
175# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
176static int (*dll_PyType_IsSubtype)(PyTypeObject *, PyTypeObject *);
177# endif
178# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
179static void* (*dll_PyObject_Malloc)(size_t);
180static void (*dll_PyObject_Free)(void*);
181# endif
182
183static HINSTANCE hinstPython = 0; /* Instance of python.dll */
184
185/* Imported exception objects */
186static PyObject *imp_PyExc_AttributeError;
187static PyObject *imp_PyExc_IndexError;
188static PyObject *imp_PyExc_KeyboardInterrupt;
189static PyObject *imp_PyExc_TypeError;
190static PyObject *imp_PyExc_ValueError;
191
192# define PyExc_AttributeError imp_PyExc_AttributeError
193# define PyExc_IndexError imp_PyExc_IndexError
194# define PyExc_KeyboardInterrupt imp_PyExc_KeyboardInterrupt
195# define PyExc_TypeError imp_PyExc_TypeError
196# define PyExc_ValueError imp_PyExc_ValueError
197
198/*
199 * Table of name to function pointer of python.
200 */
201# define PYTHON_PROC FARPROC
202static struct
203{
204 char *name;
205 PYTHON_PROC *ptr;
206} python_funcname_table[] =
207{
208 {"PyArg_Parse", (PYTHON_PROC*)&dll_PyArg_Parse},
209 {"PyArg_ParseTuple", (PYTHON_PROC*)&dll_PyArg_ParseTuple},
210 {"PyDict_SetItemString", (PYTHON_PROC*)&dll_PyDict_SetItemString},
211 {"PyErr_BadArgument", (PYTHON_PROC*)&dll_PyErr_BadArgument},
212 {"PyErr_Clear", (PYTHON_PROC*)&dll_PyErr_Clear},
213 {"PyErr_NoMemory", (PYTHON_PROC*)&dll_PyErr_NoMemory},
214 {"PyErr_Occurred", (PYTHON_PROC*)&dll_PyErr_Occurred},
215 {"PyErr_SetNone", (PYTHON_PROC*)&dll_PyErr_SetNone},
216 {"PyErr_SetString", (PYTHON_PROC*)&dll_PyErr_SetString},
217 {"PyEval_InitThreads", (PYTHON_PROC*)&dll_PyEval_InitThreads},
218 {"PyEval_RestoreThread", (PYTHON_PROC*)&dll_PyEval_RestoreThread},
219 {"PyEval_SaveThread", (PYTHON_PROC*)&dll_PyEval_SaveThread},
220# ifdef PY_CAN_RECURSE
221 {"PyGILState_Ensure", (PYTHON_PROC*)&dll_PyGILState_Ensure},
222 {"PyGILState_Release", (PYTHON_PROC*)&dll_PyGILState_Release},
223# endif
224 {"PyInt_AsLong", (PYTHON_PROC*)&dll_PyInt_AsLong},
225 {"PyInt_FromLong", (PYTHON_PROC*)&dll_PyInt_FromLong},
226 {"PyInt_Type", (PYTHON_PROC*)&dll_PyInt_Type},
227 {"PyList_GetItem", (PYTHON_PROC*)&dll_PyList_GetItem},
228 {"PyList_New", (PYTHON_PROC*)&dll_PyList_New},
229 {"PyList_SetItem", (PYTHON_PROC*)&dll_PyList_SetItem},
230 {"PyList_Size", (PYTHON_PROC*)&dll_PyList_Size},
231 {"PyList_Type", (PYTHON_PROC*)&dll_PyList_Type},
232 {"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
233 {"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
234 {"PyModule_GetDict", (PYTHON_PROC*)&dll_PyModule_GetDict},
235 {"PyRun_SimpleString", (PYTHON_PROC*)&dll_PyRun_SimpleString},
236 {"PyString_AsString", (PYTHON_PROC*)&dll_PyString_AsString},
237 {"PyString_FromString", (PYTHON_PROC*)&dll_PyString_FromString},
238 {"PyString_FromStringAndSize", (PYTHON_PROC*)&dll_PyString_FromStringAndSize},
239 {"PyString_Size", (PYTHON_PROC*)&dll_PyString_Size},
240 {"PyString_Type", (PYTHON_PROC*)&dll_PyString_Type},
241 {"PySys_SetObject", (PYTHON_PROC*)&dll_PySys_SetObject},
242 {"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
243 {"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
244 {"Py_BuildValue", (PYTHON_PROC*)&dll_Py_BuildValue},
245 {"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
246 {"Py_InitModule4", (PYTHON_PROC*)&dll_Py_InitModule4},
247 {"Py_Initialize", (PYTHON_PROC*)&dll_Py_Initialize},
248 {"_PyObject_New", (PYTHON_PROC*)&dll__PyObject_New},
249 {"PyObject_Init", (PYTHON_PROC*)&dll__PyObject_Init},
250 {"_Py_NoneStruct", (PYTHON_PROC*)&dll__Py_NoneStruct},
251# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02020000
252 {"PyType_IsSubtype", (PYTHON_PROC*)&dll_PyType_IsSubtype},
253# endif
254# if defined(PY_VERSION_HEX) && PY_VERSION_HEX >= 0x02030000
255 {"PyObject_Malloc", (PYTHON_PROC*)&dll_PyObject_Malloc},
256 {"PyObject_Free", (PYTHON_PROC*)&dll_PyObject_Free},
257# endif
258 {"", NULL},
259};
260
261/*
262 * Free python.dll
263 */
264 static void
265end_dynamic_python(void)
266{
267 if (hinstPython)
268 {
269 FreeLibrary(hinstPython);
270 hinstPython = 0;
271 }
272}
273
274/*
275 * Load library and get all pointers.
276 * Parameter 'libname' provides name of DLL.
277 * Return OK or FAIL.
278 */
279 static int
280python_runtime_link_init(char *libname, int verbose)
281{
282 int i;
283
284 if (hinstPython)
285 return OK;
286 hinstPython = LoadLibrary(libname);
287 if (!hinstPython)
288 {
289 if (verbose)
290 EMSG2(_(e_loadlib), libname);
291 return FAIL;
292 }
293
294 for (i = 0; python_funcname_table[i].ptr; ++i)
295 {
296 if ((*python_funcname_table[i].ptr = GetProcAddress(hinstPython,
297 python_funcname_table[i].name)) == NULL)
298 {
299 FreeLibrary(hinstPython);
300 hinstPython = 0;
301 if (verbose)
302 EMSG2(_(e_loadfunc), python_funcname_table[i].name);
303 return FAIL;
304 }
305 }
306 return OK;
307}
308
309/*
310 * If python is enabled (there is installed python on Windows system) return
311 * TRUE, else FALSE.
312 */
313 int
314python_enabled(verbose)
315 int verbose;
316{
317 return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK;
318}
319
320/* Load the standard Python exceptions - don't import the symbols from the
321 * DLL, as this can cause errors (importing data symbols is not reliable).
322 */
323static void get_exceptions __ARGS((void));
324
325 static void
326get_exceptions()
327{
328 PyObject *exmod = PyImport_ImportModule("exceptions");
329 PyObject *exdict = PyModule_GetDict(exmod);
330 imp_PyExc_AttributeError = PyDict_GetItemString(exdict, "AttributeError");
331 imp_PyExc_IndexError = PyDict_GetItemString(exdict, "IndexError");
332 imp_PyExc_KeyboardInterrupt = PyDict_GetItemString(exdict, "KeyboardInterrupt");
333 imp_PyExc_TypeError = PyDict_GetItemString(exdict, "TypeError");
334 imp_PyExc_ValueError = PyDict_GetItemString(exdict, "ValueError");
335 Py_XINCREF(imp_PyExc_AttributeError);
336 Py_XINCREF(imp_PyExc_IndexError);
337 Py_XINCREF(imp_PyExc_KeyboardInterrupt);
338 Py_XINCREF(imp_PyExc_TypeError);
339 Py_XINCREF(imp_PyExc_ValueError);
340 Py_XDECREF(exmod);
341}
342#endif /* DYNAMIC_PYTHON */
343
344/******************************************************
345 * Internal function prototypes.
346 */
347
348static void DoPythonCommand(exarg_T *, const char *);
349static int RangeStart;
350static int RangeEnd;
351
352static void PythonIO_Flush(void);
353static int PythonIO_Init(void);
354static int PythonMod_Init(void);
355
356/* Utility functions for the vim/python interface
357 * ----------------------------------------------
358 */
359static PyObject *GetBufferLine(buf_T *, int);
360static PyObject *GetBufferLineList(buf_T *, int, int);
361
362static int SetBufferLine(buf_T *, int, PyObject *, int *);
363static int SetBufferLineList(buf_T *, int, int, PyObject *, int *);
364static int InsertBufferLines(buf_T *, int, PyObject *, int *);
365
366static PyObject *LineToString(const char *);
367static char *StringToLine(PyObject *);
368
369static int VimErrorCheck(void);
370
371#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
372
373/******************************************************
374 * 1. Python interpreter main program.
375 */
376
377static int initialised = 0;
378
379#if PYTHON_API_VERSION < 1007 /* Python 1.4 */
380typedef PyObject PyThreadState;
381#endif /* Python 1.4 */
382
383#ifndef PY_CAN_RECURSE
384static PyThreadState* saved_python_thread = NULL;
385
386/*
387 * Suspend a thread of the Python interpreter, other threads are allowed to
388 * run.
389 */
390static void Python_SaveThread(void)
391{
392 saved_python_thread = PyEval_SaveThread();
393}
394
395/*
396 * Restore a thread of the Python interpreter, waits for other threads to
397 * block.
398 */
399static void Python_RestoreThread(void)
400{
401 PyEval_RestoreThread(saved_python_thread);
402 saved_python_thread = NULL;
403}
404#endif
405
406/*
407 * obtain a lock on the Vim data structures
408 */
409static void Python_Lock_Vim(void)
410{
411}
412
413/*
414 * release a lock on the Vim data structures
415 */
416static void Python_Release_Vim(void)
417{
418}
419
420 void
421python_end()
422{
423#ifdef DYNAMIC_PYTHON
424 end_dynamic_python();
425#endif
426}
427
428 static int
429Python_Init(void)
430{
431 if (!initialised)
432 {
433#ifdef DYNAMIC_PYTHON
434 if (!python_enabled(TRUE))
435 {
436 EMSG(_("E263: Sorry, this command is disabled, the Python library could not be loaded."));
437 goto fail;
438 }
439#endif
440
441#if !defined(MACOS) || defined(MACOS_X_UNIX)
442 Py_Initialize();
443#else
444 PyMac_Initialize();
445#endif
446 /* initialise threads */
447 PyEval_InitThreads();
448
449#ifdef DYNAMIC_PYTHON
450 get_exceptions();
451#endif
452
453 if (PythonIO_Init())
454 goto fail;
455
456 if (PythonMod_Init())
457 goto fail;
458
459#ifndef PY_CAN_RECURSE
460 /* the first python thread is vim's */
461 Python_SaveThread();
462#endif
463
464 initialised = 1;
465 }
466
467 return 0;
468
469fail:
470 /* We call PythonIO_Flush() here to print any Python errors.
471 * This is OK, as it is possible to call this function even
472 * if PythonIO_Init() has not completed successfully (it will
473 * not do anything in this case).
474 */
475 PythonIO_Flush();
476 return -1;
477}
478
479/*
480 * External interface
481 */
482 static void
483DoPythonCommand(exarg_T *eap, const char *cmd)
484{
485#ifdef PY_CAN_RECURSE
486 PyGILState_STATE pygilstate;
487#else
488 static int recursive = 0;
489#endif
490#if defined(MACOS) && !defined(MACOS_X_UNIX)
491 GrafPtr oldPort;
492#endif
493#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
494 char *saved_locale;
495#endif
496
497#ifndef PY_CAN_RECURSE
498 if (recursive)
499 {
500 EMSG(_("E659: Cannot invoke Python recursively"));
501 return;
502 }
503 ++recursive;
504#endif
505
506#if defined(MACOS) && !defined(MACOS_X_UNIX)
507 GetPort(&oldPort);
508 /* Check if the Python library is available */
509 if ((Ptr)PyMac_Initialize == (Ptr)kUnresolvedCFragSymbolAddress)
510 goto theend;
511#endif
512 if (Python_Init())
513 goto theend;
514
515 RangeStart = eap->line1;
516 RangeEnd = eap->line2;
517 Python_Release_Vim(); /* leave vim */
518
519#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
520 /* Python only works properly when the LC_NUMERIC locale is "C". */
521 saved_locale = setlocale(LC_NUMERIC, NULL);
522 if (saved_locale == NULL || STRCMP(saved_locale, "C") == 0)
523 saved_locale = NULL;
524 else
525 {
526 /* Need to make a copy, value may change when setting new locale. */
527 saved_locale = (char *)vim_strsave((char_u *)saved_locale);
528 (void)setlocale(LC_NUMERIC, "C");
529 }
530#endif
531
532#ifdef PY_CAN_RECURSE
533 pygilstate = PyGILState_Ensure();
534#else
535 Python_RestoreThread(); /* enter python */
536#endif
537
538 PyRun_SimpleString((char *)(cmd));
539
540#ifdef PY_CAN_RECURSE
541 PyGILState_Release(pygilstate);
542#else
543 Python_SaveThread(); /* leave python */
544#endif
545
546#if defined(HAVE_LOCALE_H) || defined(X_LOCALE)
547 if (saved_locale != NULL)
548 {
549 (void)setlocale(LC_NUMERIC, saved_locale);
550 vim_free(saved_locale);
551 }
552#endif
553
554 Python_Lock_Vim(); /* enter vim */
555 PythonIO_Flush();
556#if defined(MACOS) && !defined(MACOS_X_UNIX)
557 SetPort(oldPort);
558#endif
559
560theend:
561#ifndef PY_CAN_RECURSE
562 --recursive;
563#endif
564 return; /* keeps lint happy */
565}
566
567/*
568 * ":python"
569 */
570 void
571ex_python(exarg_T *eap)
572{
573 char_u *script;
574
575 script = script_get(eap, eap->arg);
576 if (!eap->skip)
577 {
578 if (script == NULL)
579 DoPythonCommand(eap, (char *)eap->arg);
580 else
581 DoPythonCommand(eap, (char *)script);
582 }
583 vim_free(script);
584}
585
586#define BUFFER_SIZE 1024
587
588/*
589 * ":pyfile"
590 */
591 void
592ex_pyfile(exarg_T *eap)
593{
594 static char buffer[BUFFER_SIZE];
595 const char *file = (char *)eap->arg;
596 char *p;
597
598 /* Have to do it like this. PyRun_SimpleFile requires you to pass a
599 * stdio file pointer, but Vim and the Python DLL are compiled with
600 * different options under Windows, meaning that stdio pointers aren't
601 * compatible between the two. Yuk.
602 *
603 * Put the string "execfile('file')" into buffer. But, we need to
604 * escape any backslashes or single quotes in the file name, so that
605 * Python won't mangle the file name.
606 */
607 strcpy(buffer, "execfile('");
608 p = buffer + 10; /* size of "execfile('" */
609
610 while (*file && p < buffer + (BUFFER_SIZE - 3))
611 {
612 if (*file == '\\' || *file == '\'')
613 *p++ = '\\';
614 *p++ = *file++;
615 }
616
617 /* If we didn't finish the file name, we hit a buffer overflow */
618 if (*file != '\0')
619 return;
620
621 /* Put in the terminating "')" and a null */
622 *p++ = '\'';
623 *p++ = ')';
624 *p++ = '\0';
625
626 /* Execute the file */
627 DoPythonCommand(eap, buffer);
628}
629
630/******************************************************
631 * 2. Python output stream: writes output via [e]msg().
632 */
633
634/* Implementation functions
635 */
636
637static PyObject *OutputGetattr(PyObject *, char *);
638static int OutputSetattr(PyObject *, char *, PyObject *);
639
640static PyObject *OutputWrite(PyObject *, PyObject *);
641static PyObject *OutputWritelines(PyObject *, PyObject *);
642
643typedef void (*writefn)(char_u *);
644static void writer(writefn fn, char_u *str, int n);
645
646/* Output object definition
647 */
648
649typedef struct
650{
651 PyObject_HEAD
652 long softspace;
653 long error;
654} OutputObject;
655
656static struct PyMethodDef OutputMethods[] = {
657 /* name, function, calling, documentation */
658 {"write", OutputWrite, 1, "" },
659 {"writelines", OutputWritelines, 1, "" },
660 { NULL, NULL, 0, NULL }
661};
662
663static PyTypeObject OutputType = {
664 PyObject_HEAD_INIT(0)
665 0,
666 "message",
667 sizeof(OutputObject),
668 0,
669
670 (destructor) 0,
671 (printfunc) 0,
672 (getattrfunc) OutputGetattr,
673 (setattrfunc) OutputSetattr,
674 (cmpfunc) 0,
675 (reprfunc) 0,
676
677 0, /* as number */
678 0, /* as sequence */
679 0, /* as mapping */
680
681 (hashfunc) 0,
682 (ternaryfunc) 0,
683 (reprfunc) 0
684};
685
686/*************/
687
688 static PyObject *
689OutputGetattr(PyObject *self, char *name)
690{
691 if (strcmp(name, "softspace") == 0)
692 return PyInt_FromLong(((OutputObject *)(self))->softspace);
693
694 return Py_FindMethod(OutputMethods, self, name);
695}
696
697 static int
698OutputSetattr(PyObject *self, char *name, PyObject *val)
699{
700 if (val == NULL) {
701 PyErr_SetString(PyExc_AttributeError, _("can't delete OutputObject attributes"));
702 return -1;
703 }
704
705 if (strcmp(name, "softspace") == 0)
706 {
707 if (!PyInt_Check(val)) {
708 PyErr_SetString(PyExc_TypeError, _("softspace must be an integer"));
709 return -1;
710 }
711
712 ((OutputObject *)(self))->softspace = PyInt_AsLong(val);
713 return 0;
714 }
715
716 PyErr_SetString(PyExc_AttributeError, _("invalid attribute"));
717 return -1;
718}
719
720/*************/
721
722 static PyObject *
723OutputWrite(PyObject *self, PyObject *args)
724{
725 int len;
726 char *str;
727 int error = ((OutputObject *)(self))->error;
728
729 if (!PyArg_ParseTuple(args, "s#", &str, &len))
730 return NULL;
731
732 Py_BEGIN_ALLOW_THREADS
733 Python_Lock_Vim();
734 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
735 Python_Release_Vim();
736 Py_END_ALLOW_THREADS
737
738 Py_INCREF(Py_None);
739 return Py_None;
740}
741
742 static PyObject *
743OutputWritelines(PyObject *self, PyObject *args)
744{
745 int n;
746 int i;
747 PyObject *list;
748 int error = ((OutputObject *)(self))->error;
749
750 if (!PyArg_ParseTuple(args, "O", &list))
751 return NULL;
752 Py_INCREF(list);
753
754 if (!PyList_Check(list)) {
755 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
756 Py_DECREF(list);
757 return NULL;
758 }
759
760 n = PyList_Size(list);
761
762 for (i = 0; i < n; ++i)
763 {
764 PyObject *line = PyList_GetItem(list, i);
765 char *str;
766 int len;
767
768 if (!PyArg_Parse(line, "s#", &str, &len)) {
769 PyErr_SetString(PyExc_TypeError, _("writelines() requires list of strings"));
770 Py_DECREF(list);
771 return NULL;
772 }
773
774 Py_BEGIN_ALLOW_THREADS
775 Python_Lock_Vim();
776 writer((writefn)(error ? emsg : msg), (char_u *)str, len);
777 Python_Release_Vim();
778 Py_END_ALLOW_THREADS
779 }
780
781 Py_DECREF(list);
782 Py_INCREF(Py_None);
783 return Py_None;
784}
785
786/* Output buffer management
787 */
788
789static char_u *buffer = NULL;
790static int buffer_len = 0;
791static int buffer_size = 0;
792
793static writefn old_fn = NULL;
794
795 static void
796buffer_ensure(int n)
797{
798 int new_size;
799 char_u *new_buffer;
800
801 if (n < buffer_size)
802 return;
803
804 new_size = buffer_size;
805 while (new_size < n)
806 new_size += 80;
807
808 if (new_size != buffer_size)
809 {
810 new_buffer = alloc((unsigned)new_size);
811 if (new_buffer == NULL)
812 return;
813
814 if (buffer)
815 {
816 memcpy(new_buffer, buffer, buffer_len);
817 vim_free(buffer);
818 }
819
820 buffer = new_buffer;
821 buffer_size = new_size;
822 }
823}
824
825 static void
826PythonIO_Flush(void)
827{
828 if (old_fn && buffer_len)
829 {
830 buffer[buffer_len] = 0;
831 old_fn(buffer);
832 }
833
834 buffer_len = 0;
835}
836
837 static void
838writer(writefn fn, char_u *str, int n)
839{
840 char_u *ptr;
841
842 if (fn != old_fn && old_fn != NULL)
843 PythonIO_Flush();
844
845 old_fn = fn;
846
847 while (n > 0 && (ptr = memchr(str, '\n', n)) != NULL)
848 {
849 int len = ptr - str;
850
851 buffer_ensure(buffer_len + len + 1);
852
853 memcpy(buffer + buffer_len, str, len);
854 buffer_len += len;
855 buffer[buffer_len] = 0;
856 fn(buffer);
857 str = ptr + 1;
858 n -= len + 1;
859 buffer_len = 0;
860 }
861
862 /* Put the remaining text into the buffer for later printing */
863 buffer_ensure(buffer_len + n + 1);
864 memcpy(buffer + buffer_len, str, n);
865 buffer_len += n;
866}
867
868/***************/
869
870static OutputObject Output =
871{
872 PyObject_HEAD_INIT(&OutputType)
873 0,
874 0
875};
876
877static OutputObject Error =
878{
879 PyObject_HEAD_INIT(&OutputType)
880 0,
881 1
882};
883
884 static int
885PythonIO_Init(void)
886{
887 /* Fixups... */
888 OutputType.ob_type = &PyType_Type;
889
890 PySys_SetObject("stdout", (PyObject *)(&Output));
891 PySys_SetObject("stderr", (PyObject *)(&Error));
892
893 if (PyErr_Occurred())
894 {
895 EMSG(_("E264: Python: Error initialising I/O objects"));
896 return -1;
897 }
898
899 return 0;
900}
901
902/******************************************************
903 * 3. Implementation of the Vim module for Python
904 */
905
906/* Vim module - Implementation functions
907 * -------------------------------------
908 */
909
910static PyObject *VimError;
911
912static PyObject *VimCommand(PyObject *, PyObject *);
913static PyObject *VimEval(PyObject *, PyObject *);
914
915/* Window type - Implementation functions
916 * --------------------------------------
917 */
918
919typedef struct
920{
921 PyObject_HEAD
922 win_T *win;
923}
924WindowObject;
925
926#define INVALID_WINDOW_VALUE ((win_T *)(-1))
927
928#define WindowType_Check(obj) ((obj)->ob_type == &WindowType)
929
930static PyObject *WindowNew(win_T *);
931
932static void WindowDestructor(PyObject *);
933static PyObject *WindowGetattr(PyObject *, char *);
934static int WindowSetattr(PyObject *, char *, PyObject *);
935static PyObject *WindowRepr(PyObject *);
936
937/* Buffer type - Implementation functions
938 * --------------------------------------
939 */
940
941typedef struct
942{
943 PyObject_HEAD
944 buf_T *buf;
945}
946BufferObject;
947
948#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
949
950#define BufferType_Check(obj) ((obj)->ob_type == &BufferType)
951
952static PyObject *BufferNew (buf_T *);
953
954static void BufferDestructor(PyObject *);
955static PyObject *BufferGetattr(PyObject *, char *);
956static PyObject *BufferRepr(PyObject *);
957
958static int BufferLength(PyObject *);
959static PyObject *BufferItem(PyObject *, int);
960static PyObject *BufferSlice(PyObject *, int, int);
961static int BufferAssItem(PyObject *, int, PyObject *);
962static int BufferAssSlice(PyObject *, int, int, PyObject *);
963
964static PyObject *BufferAppend(PyObject *, PyObject *);
965static PyObject *BufferMark(PyObject *, PyObject *);
966static PyObject *BufferRange(PyObject *, PyObject *);
967
968/* Line range type - Implementation functions
969 * --------------------------------------
970 */
971
972typedef struct
973{
974 PyObject_HEAD
975 BufferObject *buf;
976 int start;
977 int end;
978}
979RangeObject;
980
981#define RangeType_Check(obj) ((obj)->ob_type == &RangeType)
982
983static PyObject *RangeNew(buf_T *, int, int);
984
985static void RangeDestructor(PyObject *);
986static PyObject *RangeGetattr(PyObject *, char *);
987static PyObject *RangeRepr(PyObject *);
988
989static int RangeLength(PyObject *);
990static PyObject *RangeItem(PyObject *, int);
991static PyObject *RangeSlice(PyObject *, int, int);
992static int RangeAssItem(PyObject *, int, PyObject *);
993static int RangeAssSlice(PyObject *, int, int, PyObject *);
994
995static PyObject *RangeAppend(PyObject *, PyObject *);
996
997/* Window list type - Implementation functions
998 * -------------------------------------------
999 */
1000
1001static int WinListLength(PyObject *);
1002static PyObject *WinListItem(PyObject *, int);
1003
1004/* Buffer list type - Implementation functions
1005 * -------------------------------------------
1006 */
1007
1008static int BufListLength(PyObject *);
1009static PyObject *BufListItem(PyObject *, int);
1010
1011/* Current objects type - Implementation functions
1012 * -----------------------------------------------
1013 */
1014
1015static PyObject *CurrentGetattr(PyObject *, char *);
1016static int CurrentSetattr(PyObject *, char *, PyObject *);
1017
1018/* Vim module - Definitions
1019 */
1020
1021static struct PyMethodDef VimMethods[] = {
1022 /* name, function, calling, documentation */
1023 {"command", VimCommand, 1, "" },
1024 {"eval", VimEval, 1, "" },
1025 { NULL, NULL, 0, NULL }
1026};
1027
1028/* Vim module - Implementation
1029 */
1030/*ARGSUSED*/
1031 static PyObject *
1032VimCommand(PyObject *self, PyObject *args)
1033{
1034 char *cmd;
1035 PyObject *result;
1036
1037 if (!PyArg_ParseTuple(args, "s", &cmd))
1038 return NULL;
1039
1040 PyErr_Clear();
1041
1042 Py_BEGIN_ALLOW_THREADS
1043 Python_Lock_Vim();
1044
1045 do_cmdline_cmd((char_u *)cmd);
1046 update_screen(VALID);
1047
1048 Python_Release_Vim();
1049 Py_END_ALLOW_THREADS
1050
1051 if (VimErrorCheck())
1052 result = NULL;
1053 else
1054 result = Py_None;
1055
1056 Py_XINCREF(result);
1057 return result;
1058}
1059
1060/*ARGSUSED*/
1061 static PyObject *
1062VimEval(PyObject *self, PyObject *args)
1063{
1064#ifdef FEAT_EVAL
1065 char *expr;
1066 char *str;
1067 PyObject *result;
1068
1069 if (!PyArg_ParseTuple(args, "s", &expr))
1070 return NULL;
1071
1072 Py_BEGIN_ALLOW_THREADS
1073 Python_Lock_Vim();
1074 str = (char *)eval_to_string((char_u *)expr, NULL);
1075 Python_Release_Vim();
1076 Py_END_ALLOW_THREADS
1077
1078 if (str == NULL)
1079 {
1080 PyErr_SetVim(_("invalid expression"));
1081 return NULL;
1082 }
1083
1084 result = Py_BuildValue("s", str);
1085
1086 Py_BEGIN_ALLOW_THREADS
1087 Python_Lock_Vim();
1088 vim_free(str);
1089 Python_Release_Vim();
1090 Py_END_ALLOW_THREADS
1091
1092 return result;
1093#else
1094 PyErr_SetVim(_("expressions disabled at compile time"));
1095 return NULL;
1096#endif
1097}
1098
1099/* Common routines for buffers and line ranges
1100 * -------------------------------------------
1101 */
1102 static int
1103CheckBuffer(BufferObject *this)
1104{
1105 if (this->buf == INVALID_BUFFER_VALUE)
1106 {
1107 PyErr_SetVim(_("attempt to refer to deleted buffer"));
1108 return -1;
1109 }
1110
1111 return 0;
1112}
1113
1114 static PyObject *
1115RBItem(BufferObject *self, int n, int start, int end)
1116{
1117 if (CheckBuffer(self))
1118 return NULL;
1119
1120 if (n < 0 || n > end - start)
1121 {
1122 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1123 return NULL;
1124 }
1125
1126 return GetBufferLine(self->buf, n+start);
1127}
1128
1129 static PyObject *
1130RBSlice(BufferObject *self, int lo, int hi, int start, int end)
1131{
1132 int size;
1133
1134 if (CheckBuffer(self))
1135 return NULL;
1136
1137 size = end - start + 1;
1138
1139 if (lo < 0)
1140 lo = 0;
1141 else if (lo > size)
1142 lo = size;
1143 if (hi < 0)
1144 hi = 0;
1145 if (hi < lo)
1146 hi = lo;
1147 else if (hi > size)
1148 hi = size;
1149
1150 return GetBufferLineList(self->buf, lo+start, hi+start);
1151}
1152
1153 static int
1154RBAssItem(BufferObject *self, int n, PyObject *val, int start, int end, int *new_end)
1155{
1156 int len_change;
1157
1158 if (CheckBuffer(self))
1159 return -1;
1160
1161 if (n < 0 || n > end - start)
1162 {
1163 PyErr_SetString(PyExc_IndexError, _("line number out of range"));
1164 return -1;
1165 }
1166
1167 if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL)
1168 return -1;
1169
1170 if (new_end)
1171 *new_end = end + len_change;
1172
1173 return 0;
1174}
1175
1176 static int
1177RBAssSlice(BufferObject *self, int lo, int hi, PyObject *val, int start, int end, int *new_end)
1178{
1179 int size;
1180 int len_change;
1181
1182 /* Self must be a valid buffer */
1183 if (CheckBuffer(self))
1184 return -1;
1185
1186 /* Sort out the slice range */
1187 size = end - start + 1;
1188
1189 if (lo < 0)
1190 lo = 0;
1191 else if (lo > size)
1192 lo = size;
1193 if (hi < 0)
1194 hi = 0;
1195 if (hi < lo)
1196 hi = lo;
1197 else if (hi > size)
1198 hi = size;
1199
1200 if (SetBufferLineList(self->buf, lo+start, hi+start, val, &len_change) == FAIL)
1201 return -1;
1202
1203 if (new_end)
1204 *new_end = end + len_change;
1205
1206 return 0;
1207}
1208
1209 static PyObject *
1210RBAppend(BufferObject *self, PyObject *args, int start, int end, int *new_end)
1211{
1212 PyObject *lines;
1213 int len_change;
1214 int max;
1215 int n;
1216
1217 if (CheckBuffer(self))
1218 return NULL;
1219
1220 max = n = end - start + 1;
1221
1222 if (!PyArg_ParseTuple(args, "O|i", &lines, &n))
1223 return NULL;
1224
1225 if (n < 0 || n > max)
1226 {
1227 PyErr_SetString(PyExc_ValueError, _("line number out of range"));
1228 return NULL;
1229 }
1230
1231 if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL)
1232 return NULL;
1233
1234 if (new_end)
1235 *new_end = end + len_change;
1236
1237 Py_INCREF(Py_None);
1238 return Py_None;
1239}
1240
1241
1242/* Buffer object - Definitions
1243 */
1244
1245static struct PyMethodDef BufferMethods[] = {
1246 /* name, function, calling, documentation */
1247 {"append", BufferAppend, 1, "" },
1248 {"mark", BufferMark, 1, "" },
1249 {"range", BufferRange, 1, "" },
1250 { NULL, NULL, 0, NULL }
1251};
1252
1253static PySequenceMethods BufferAsSeq = {
1254 (inquiry) BufferLength, /* sq_length, len(x) */
1255 (binaryfunc) 0, /* BufferConcat, */ /* sq_concat, x+y */
1256 (intargfunc) 0, /* BufferRepeat, */ /* sq_repeat, x*n */
1257 (intargfunc) BufferItem, /* sq_item, x[i] */
1258 (intintargfunc) BufferSlice, /* sq_slice, x[i:j] */
1259 (intobjargproc) BufferAssItem, /* sq_ass_item, x[i]=v */
1260 (intintobjargproc) BufferAssSlice, /* sq_ass_slice, x[i:j]=v */
1261};
1262
1263static PyTypeObject BufferType = {
1264 PyObject_HEAD_INIT(0)
1265 0,
1266 "buffer",
1267 sizeof(BufferObject),
1268 0,
1269
1270 (destructor) BufferDestructor, /* tp_dealloc, refcount==0 */
1271 (printfunc) 0, /* tp_print, print x */
1272 (getattrfunc) BufferGetattr, /* tp_getattr, x.attr */
1273 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1274 (cmpfunc) 0, /* tp_compare, x>y */
1275 (reprfunc) BufferRepr, /* tp_repr, `x`, print x */
1276
1277 0, /* as number */
1278 &BufferAsSeq, /* as sequence */
1279 0, /* as mapping */
1280
1281 (hashfunc) 0, /* tp_hash, dict(x) */
1282 (ternaryfunc) 0, /* tp_call, x() */
1283 (reprfunc) 0, /* tp_str, str(x) */
1284};
1285
1286/* Buffer object - Implementation
1287 */
1288
1289 static PyObject *
1290BufferNew(buf_T *buf)
1291{
1292 /* We need to handle deletion of buffers underneath us.
1293 * If we add a "python_ref" field to the buf_T structure,
1294 * then we can get at it in buf_freeall() in vim. We then
1295 * need to create only ONE Python object per buffer - if
1296 * we try to create a second, just INCREF the existing one
1297 * and return it. The (single) Python object referring to
1298 * the buffer is stored in "python_ref".
1299 * Question: what to do on a buf_freeall(). We'll probably
1300 * have to either delete the Python object (DECREF it to
1301 * zero - a bad idea, as it leaves dangling refs!) or
1302 * set the buf_T * value to an invalid value (-1?), which
1303 * means we need checks in all access functions... Bah.
1304 */
1305
1306 BufferObject *self;
1307
1308 if (buf->python_ref)
1309 {
1310 self = buf->python_ref;
1311 Py_INCREF(self);
1312 }
1313 else
1314 {
1315 self = PyObject_NEW(BufferObject, &BufferType);
1316 if (self == NULL)
1317 return NULL;
1318 self->buf = buf;
1319 buf->python_ref = self;
1320 }
1321
1322 return (PyObject *)(self);
1323}
1324
1325 static void
1326BufferDestructor(PyObject *self)
1327{
1328 BufferObject *this = (BufferObject *)(self);
1329
1330 if (this->buf && this->buf != INVALID_BUFFER_VALUE)
1331 this->buf->python_ref = NULL;
1332
1333 PyMem_DEL(self);
1334}
1335
1336 static PyObject *
1337BufferGetattr(PyObject *self, char *name)
1338{
1339 BufferObject *this = (BufferObject *)(self);
1340
1341 if (CheckBuffer(this))
1342 return NULL;
1343
1344 if (strcmp(name, "name") == 0)
1345 return Py_BuildValue("s",this->buf->b_ffname);
1346 else if (strcmp(name, "number") == 0)
1347 return Py_BuildValue("i",this->buf->b_fnum);
1348 else if (strcmp(name,"__members__") == 0)
1349 return Py_BuildValue("[ss]", "name", "number");
1350 else
1351 return Py_FindMethod(BufferMethods, self, name);
1352}
1353
1354 static PyObject *
1355BufferRepr(PyObject *self)
1356{
1357 static char repr[50];
1358 BufferObject *this = (BufferObject *)(self);
1359
1360 if (this->buf == INVALID_BUFFER_VALUE)
1361 {
1362 sprintf(repr, _("<buffer object (deleted) at %8lX>"), (long)(self));
1363 return PyString_FromString(repr);
1364 }
1365 else
1366 {
1367 char *name = (char *)this->buf->b_fname;
1368 int len;
1369
1370 if (name == NULL)
1371 name = "";
1372 len = strlen(name);
1373
1374 if (len > 35)
1375 name = name + (35 - len);
1376
1377 sprintf(repr, "<buffer %s%s>", len > 35 ? "..." : "", name);
1378
1379 return PyString_FromString(repr);
1380 }
1381}
1382
1383/******************/
1384
1385 static int
1386BufferLength(PyObject *self)
1387{
1388 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1389 if (CheckBuffer((BufferObject *)(self)))
1390 return -1; /* ??? */
1391
1392 return (((BufferObject *)(self))->buf->b_ml.ml_line_count);
1393}
1394
1395 static PyObject *
1396BufferItem(PyObject *self, int n)
1397{
1398 return RBItem((BufferObject *)(self), n, 1,
1399 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1400}
1401
1402 static PyObject *
1403BufferSlice(PyObject *self, int lo, int hi)
1404{
1405 return RBSlice((BufferObject *)(self), lo, hi, 1,
1406 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count);
1407}
1408
1409 static int
1410BufferAssItem(PyObject *self, int n, PyObject *val)
1411{
1412 return RBAssItem((BufferObject *)(self), n, val, 1,
1413 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1414 NULL);
1415}
1416
1417 static int
1418BufferAssSlice(PyObject *self, int lo, int hi, PyObject *val)
1419{
1420 return RBAssSlice((BufferObject *)(self), lo, hi, val, 1,
1421 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1422 NULL);
1423}
1424
1425 static PyObject *
1426BufferAppend(PyObject *self, PyObject *args)
1427{
1428 return RBAppend((BufferObject *)(self), args, 1,
1429 (int)((BufferObject *)(self))->buf->b_ml.ml_line_count,
1430 NULL);
1431}
1432
1433 static PyObject *
1434BufferMark(PyObject *self, PyObject *args)
1435{
1436 pos_T *posp;
1437 char mark;
1438 buf_T *curbuf_save;
1439
1440 if (CheckBuffer((BufferObject *)(self)))
1441 return NULL;
1442
1443 if (!PyArg_ParseTuple(args, "c", &mark))
1444 return NULL;
1445
1446 curbuf_save = curbuf;
1447 curbuf = ((BufferObject *)(self))->buf;
1448 posp = getmark(mark, FALSE);
1449 curbuf = curbuf_save;
1450
1451 if (posp == NULL)
1452 {
1453 PyErr_SetVim(_("invalid mark name"));
1454 return NULL;
1455 }
1456
1457 /* Ckeck for keyboard interrupt */
1458 if (VimErrorCheck())
1459 return NULL;
1460
1461 if (posp->lnum <= 0)
1462 {
1463 /* Or raise an error? */
1464 Py_INCREF(Py_None);
1465 return Py_None;
1466 }
1467
1468 return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col));
1469}
1470
1471 static PyObject *
1472BufferRange(PyObject *self, PyObject *args)
1473{
1474 int start;
1475 int end;
1476
1477 if (CheckBuffer((BufferObject *)(self)))
1478 return NULL;
1479
1480 if (!PyArg_ParseTuple(args, "ii", &start, &end))
1481 return NULL;
1482
1483 return RangeNew(((BufferObject *)(self))->buf, start, end);
1484}
1485
1486/* Line range object - Definitions
1487 */
1488
1489static struct PyMethodDef RangeMethods[] = {
1490 /* name, function, calling, documentation */
1491 {"append", RangeAppend, 1, "" },
1492 { NULL, NULL, 0, NULL }
1493};
1494
1495static PySequenceMethods RangeAsSeq = {
1496 (inquiry) RangeLength, /* sq_length, len(x) */
1497 (binaryfunc) 0, /* RangeConcat, */ /* sq_concat, x+y */
1498 (intargfunc) 0, /* RangeRepeat, */ /* sq_repeat, x*n */
1499 (intargfunc) RangeItem, /* sq_item, x[i] */
1500 (intintargfunc) RangeSlice, /* sq_slice, x[i:j] */
1501 (intobjargproc) RangeAssItem, /* sq_ass_item, x[i]=v */
1502 (intintobjargproc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */
1503};
1504
1505static PyTypeObject RangeType = {
1506 PyObject_HEAD_INIT(0)
1507 0,
1508 "range",
1509 sizeof(RangeObject),
1510 0,
1511
1512 (destructor) RangeDestructor, /* tp_dealloc, refcount==0 */
1513 (printfunc) 0, /* tp_print, print x */
1514 (getattrfunc) RangeGetattr, /* tp_getattr, x.attr */
1515 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1516 (cmpfunc) 0, /* tp_compare, x>y */
1517 (reprfunc) RangeRepr, /* tp_repr, `x`, print x */
1518
1519 0, /* as number */
1520 &RangeAsSeq, /* as sequence */
1521 0, /* as mapping */
1522
1523 (hashfunc) 0, /* tp_hash, dict(x) */
1524 (ternaryfunc) 0, /* tp_call, x() */
1525 (reprfunc) 0, /* tp_str, str(x) */
1526};
1527
1528/* Line range object - Implementation
1529 */
1530
1531 static PyObject *
1532RangeNew(buf_T *buf, int start, int end)
1533{
1534 BufferObject *bufr;
1535 RangeObject *self;
1536 self = PyObject_NEW(RangeObject, &RangeType);
1537 if (self == NULL)
1538 return NULL;
1539
1540 bufr = (BufferObject *)BufferNew(buf);
1541 if (bufr == NULL)
1542 {
1543 PyMem_DEL(self);
1544 return NULL;
1545 }
1546 Py_INCREF(bufr);
1547
1548 self->buf = bufr;
1549 self->start = start;
1550 self->end = end;
1551
1552 return (PyObject *)(self);
1553}
1554
1555 static void
1556RangeDestructor(PyObject *self)
1557{
1558 Py_DECREF(((RangeObject *)(self))->buf);
1559 PyMem_DEL(self);
1560}
1561
1562 static PyObject *
1563RangeGetattr(PyObject *self, char *name)
1564{
1565 if (strcmp(name, "start") == 0)
1566 return Py_BuildValue("i",((RangeObject *)(self))->start - 1);
1567 else if (strcmp(name, "end") == 0)
1568 return Py_BuildValue("i",((RangeObject *)(self))->end - 1);
1569 else
1570 return Py_FindMethod(RangeMethods, self, name);
1571}
1572
1573 static PyObject *
1574RangeRepr(PyObject *self)
1575{
1576 static char repr[75];
1577 RangeObject *this = (RangeObject *)(self);
1578
1579 if (this->buf->buf == INVALID_BUFFER_VALUE)
1580 {
1581 sprintf(repr, "<range object (for deleted buffer) at %8lX>",
1582 (long)(self));
1583 return PyString_FromString(repr);
1584 }
1585 else
1586 {
1587 char *name = (char *)this->buf->buf->b_fname;
1588 int len;
1589
1590 if (name == NULL)
1591 name = "";
1592 len = strlen(name);
1593
1594 if (len > 45)
1595 name = name + (45 - len);
1596
1597 sprintf(repr, "<range %s%s (%d:%d)>",
1598 len > 45 ? "..." : "", name,
1599 this->start, this->end);
1600
1601 return PyString_FromString(repr);
1602 }
1603}
1604
1605/****************/
1606
1607 static int
1608RangeLength(PyObject *self)
1609{
1610 /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */
1611 if (CheckBuffer(((RangeObject *)(self))->buf))
1612 return -1; /* ??? */
1613
1614 return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1);
1615}
1616
1617 static PyObject *
1618RangeItem(PyObject *self, int n)
1619{
1620 return RBItem(((RangeObject *)(self))->buf, n,
1621 ((RangeObject *)(self))->start,
1622 ((RangeObject *)(self))->end);
1623}
1624
1625 static PyObject *
1626RangeSlice(PyObject *self, int lo, int hi)
1627{
1628 return RBSlice(((RangeObject *)(self))->buf, lo, hi,
1629 ((RangeObject *)(self))->start,
1630 ((RangeObject *)(self))->end);
1631}
1632
1633 static int
1634RangeAssItem(PyObject *self, int n, PyObject *val)
1635{
1636 return RBAssItem(((RangeObject *)(self))->buf, n, val,
1637 ((RangeObject *)(self))->start,
1638 ((RangeObject *)(self))->end,
1639 &((RangeObject *)(self))->end);
1640}
1641
1642 static int
1643RangeAssSlice(PyObject *self, int lo, int hi, PyObject *val)
1644{
1645 return RBAssSlice(((RangeObject *)(self))->buf, lo, hi, val,
1646 ((RangeObject *)(self))->start,
1647 ((RangeObject *)(self))->end,
1648 &((RangeObject *)(self))->end);
1649}
1650
1651 static PyObject *
1652RangeAppend(PyObject *self, PyObject *args)
1653{
1654 return RBAppend(((RangeObject *)(self))->buf, args,
1655 ((RangeObject *)(self))->start,
1656 ((RangeObject *)(self))->end,
1657 &((RangeObject *)(self))->end);
1658}
1659
1660/* Buffer list object - Definitions
1661 */
1662
1663typedef struct
1664{
1665 PyObject_HEAD
1666}
1667BufListObject;
1668
1669static PySequenceMethods BufListAsSeq = {
1670 (inquiry) BufListLength, /* sq_length, len(x) */
1671 (binaryfunc) 0, /* sq_concat, x+y */
1672 (intargfunc) 0, /* sq_repeat, x*n */
1673 (intargfunc) BufListItem, /* sq_item, x[i] */
1674 (intintargfunc) 0, /* sq_slice, x[i:j] */
1675 (intobjargproc) 0, /* sq_ass_item, x[i]=v */
1676 (intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
1677};
1678
1679static PyTypeObject BufListType = {
1680 PyObject_HEAD_INIT(0)
1681 0,
1682 "buffer list",
1683 sizeof(BufListObject),
1684 0,
1685
1686 (destructor) 0, /* tp_dealloc, refcount==0 */
1687 (printfunc) 0, /* tp_print, print x */
1688 (getattrfunc) 0, /* tp_getattr, x.attr */
1689 (setattrfunc) 0, /* tp_setattr, x.attr=v */
1690 (cmpfunc) 0, /* tp_compare, x>y */
1691 (reprfunc) 0, /* tp_repr, `x`, print x */
1692
1693 0, /* as number */
1694 &BufListAsSeq, /* as sequence */
1695 0, /* as mapping */
1696
1697 (hashfunc) 0, /* tp_hash, dict(x) */
1698 (ternaryfunc) 0, /* tp_call, x() */
1699 (reprfunc) 0, /* tp_str, str(x) */
1700};
1701
1702/* Buffer list object - Implementation
1703 */
1704
1705/*ARGSUSED*/
1706 static int
1707BufListLength(PyObject *self)
1708{
1709 buf_T *b = firstbuf;
1710 int n = 0;
1711
1712 while (b)
1713 {
1714 ++n;
1715 b = b->b_next;
1716 }
1717
1718 return n;
1719}
1720
1721/*ARGSUSED*/
1722 static PyObject *
1723BufListItem(PyObject *self, int n)
1724{
1725 buf_T *b;
1726
1727 for (b = firstbuf; b; b = b->b_next, --n)
1728 {
1729 if (n == 0)
1730 return BufferNew(b);
1731 }
1732
1733 PyErr_SetString(PyExc_IndexError, _("no such buffer"));
1734 return NULL;
1735}
1736
1737/* Window object - Definitions
1738 */
1739
1740static struct PyMethodDef WindowMethods[] = {
1741 /* name, function, calling, documentation */
1742 { NULL, NULL, 0, NULL }
1743};
1744
1745static PyTypeObject WindowType = {
1746 PyObject_HEAD_INIT(0)
1747 0,
1748 "window",
1749 sizeof(WindowObject),
1750 0,
1751
1752 (destructor) WindowDestructor, /* tp_dealloc, refcount==0 */
1753 (printfunc) 0, /* tp_print, print x */
1754 (getattrfunc) WindowGetattr, /* tp_getattr, x.attr */
1755 (setattrfunc) WindowSetattr, /* tp_setattr, x.attr=v */
1756 (cmpfunc) 0, /* tp_compare, x>y */
1757 (reprfunc) WindowRepr, /* tp_repr, `x`, print x */
1758
1759 0, /* as number */
1760 0, /* as sequence */
1761 0, /* as mapping */
1762
1763 (hashfunc) 0, /* tp_hash, dict(x) */
1764 (ternaryfunc) 0, /* tp_call, x() */
1765 (reprfunc) 0, /* tp_str, str(x) */
1766};
1767
1768/* Window object - Implementation
1769 */
1770
1771 static PyObject *
1772WindowNew(win_T *win)
1773{
1774 /* We need to handle deletion of windows underneath us.
1775 * If we add a "python_ref" field to the win_T structure,
1776 * then we can get at it in win_free() in vim. We then
1777 * need to create only ONE Python object per window - if
1778 * we try to create a second, just INCREF the existing one
1779 * and return it. The (single) Python object referring to
1780 * the window is stored in "python_ref".
1781 * On a win_free() we set the Python object's win_T* field
1782 * to an invalid value. We trap all uses of a window
1783 * object, and reject them if the win_T* field is invalid.
1784 */
1785
1786 WindowObject *self;
1787
1788 if (win->python_ref)
1789 {
1790 self = win->python_ref;
1791 Py_INCREF(self);
1792 }
1793 else
1794 {
1795 self = PyObject_NEW(WindowObject, &WindowType);
1796 if (self == NULL)
1797 return NULL;
1798 self->win = win;
1799 win->python_ref = self;
1800 }
1801
1802 return (PyObject *)(self);
1803}
1804
1805 static void
1806WindowDestructor(PyObject *self)
1807{
1808 WindowObject *this = (WindowObject *)(self);
1809
1810 if (this->win && this->win != INVALID_WINDOW_VALUE)
1811 this->win->python_ref = NULL;
1812
1813 PyMem_DEL(self);
1814}
1815
1816 static int
1817CheckWindow(WindowObject *this)
1818{
1819 if (this->win == INVALID_WINDOW_VALUE)
1820 {
1821 PyErr_SetVim(_("attempt to refer to deleted window"));
1822 return -1;
1823 }
1824
1825 return 0;
1826}
1827
1828 static PyObject *
1829WindowGetattr(PyObject *self, char *name)
1830{
1831 WindowObject *this = (WindowObject *)(self);
1832
1833 if (CheckWindow(this))
1834 return NULL;
1835
1836 if (strcmp(name, "buffer") == 0)
1837 return (PyObject *)BufferNew(this->win->w_buffer);
1838 else if (strcmp(name, "cursor") == 0)
1839 {
1840 pos_T *pos = &this->win->w_cursor;
1841
1842 return Py_BuildValue("(ll)", (long)(pos->lnum), (long)(pos->col));
1843 }
1844 else if (strcmp(name, "height") == 0)
1845 return Py_BuildValue("l", (long)(this->win->w_height));
1846#ifdef FEAT_VERTSPLIT
1847 else if (strcmp(name, "width") == 0)
1848 return Py_BuildValue("l", (long)(W_WIDTH(this->win)));
1849#endif
1850 else if (strcmp(name,"__members__") == 0)
1851 return Py_BuildValue("[sss]", "buffer", "cursor", "height");
1852 else
1853 return Py_FindMethod(WindowMethods, self, name);
1854}
1855
1856 static int
1857WindowSetattr(PyObject *self, char *name, PyObject *val)
1858{
1859 WindowObject *this = (WindowObject *)(self);
1860
1861 if (CheckWindow(this))
1862 return -1;
1863
1864 if (strcmp(name, "buffer") == 0)
1865 {
1866 PyErr_SetString(PyExc_TypeError, _("readonly attribute"));
1867 return -1;
1868 }
1869 else if (strcmp(name, "cursor") == 0)
1870 {
1871 long lnum;
1872 long col;
1873
1874 if (!PyArg_Parse(val, "(ll)", &lnum, &col))
1875 return -1;
1876
1877 if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count)
1878 {
1879 PyErr_SetVim(_("cursor position outside buffer"));
1880 return -1;
1881 }
1882
1883 /* Check for keyboard interrupts */
1884 if (VimErrorCheck())
1885 return -1;
1886
1887 /* NO CHECK ON COLUMN - SEEMS NOT TO MATTER */
1888
1889 this->win->w_cursor.lnum = lnum;
1890 this->win->w_cursor.col = col;
1891 update_screen(VALID);
1892
1893 return 0;
1894 }
1895 else if (strcmp(name, "height") == 0)
1896 {
1897 int height;
1898 win_T *savewin;
1899
1900 if (!PyArg_Parse(val, "i", &height))
1901 return -1;
1902
1903#ifdef FEAT_GUI
1904 need_mouse_correct = TRUE;
1905#endif
1906 savewin = curwin;
1907 curwin = this->win;
1908 win_setheight(height);
1909 curwin = savewin;
1910
1911 /* Check for keyboard interrupts */
1912 if (VimErrorCheck())
1913 return -1;
1914
1915 return 0;
1916 }
1917#ifdef FEAT_VERTSPLIT
1918 else if (strcmp(name, "width") == 0)
1919 {
1920 int width;
1921 win_T *savewin;
1922
1923 if (!PyArg_Parse(val, "i", &width))
1924 return -1;
1925
1926#ifdef FEAT_GUI
1927 need_mouse_correct = TRUE;
1928#endif
1929 savewin = curwin;
1930 curwin = this->win;
1931 win_setwidth(width);
1932 curwin = savewin;
1933
1934 /* Check for keyboard interrupts */
1935 if (VimErrorCheck())
1936 return -1;
1937
1938 return 0;
1939 }
1940#endif
1941 else
1942 {
1943 PyErr_SetString(PyExc_AttributeError, name);
1944 return -1;
1945 }
1946}
1947
1948 static PyObject *
1949WindowRepr(PyObject *self)
1950{
1951 static char repr[50];
1952 WindowObject *this = (WindowObject *)(self);
1953
1954 if (this->win == INVALID_WINDOW_VALUE)
1955 {
1956 sprintf(repr, _("<window object (deleted) at %.8lX>"), (long)(self));
1957 return PyString_FromString(repr);
1958 }
1959 else
1960 {
1961 int i = 0;
1962 win_T *w;
1963
1964 for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w))
1965 ++i;
1966
1967 if (w == NULL)
1968 sprintf(repr, _("<window object (unknown) at %.8lX>"), (long)(self));
1969 else
1970 sprintf(repr, _("<window %d>"), i);
1971
1972 return PyString_FromString(repr);
1973 }
1974}
1975
1976/* Window list object - Definitions
1977 */
1978
1979typedef struct
1980{
1981 PyObject_HEAD
1982}
1983WinListObject;
1984
1985static PySequenceMethods WinListAsSeq = {
1986 (inquiry) WinListLength, /* sq_length, len(x) */
1987 (binaryfunc) 0, /* sq_concat, x+y */
1988 (intargfunc) 0, /* sq_repeat, x*n */
1989 (intargfunc) WinListItem, /* sq_item, x[i] */
1990 (intintargfunc) 0, /* sq_slice, x[i:j] */
1991 (intobjargproc) 0, /* sq_ass_item, x[i]=v */
1992 (intintobjargproc) 0, /* sq_ass_slice, x[i:j]=v */
1993};
1994
1995static PyTypeObject WinListType = {
1996 PyObject_HEAD_INIT(0)
1997 0,
1998 "window list",
1999 sizeof(WinListObject),
2000 0,
2001
2002 (destructor) 0, /* tp_dealloc, refcount==0 */
2003 (printfunc) 0, /* tp_print, print x */
2004 (getattrfunc) 0, /* tp_getattr, x.attr */
2005 (setattrfunc) 0, /* tp_setattr, x.attr=v */
2006 (cmpfunc) 0, /* tp_compare, x>y */
2007 (reprfunc) 0, /* tp_repr, `x`, print x */
2008
2009 0, /* as number */
2010 &WinListAsSeq, /* as sequence */
2011 0, /* as mapping */
2012
2013 (hashfunc) 0, /* tp_hash, dict(x) */
2014 (ternaryfunc) 0, /* tp_call, x() */
2015 (reprfunc) 0, /* tp_str, str(x) */
2016};
2017
2018/* Window list object - Implementation
2019 */
2020/*ARGSUSED*/
2021 static int
2022WinListLength(PyObject *self)
2023{
2024 win_T *w = firstwin;
2025 int n = 0;
2026
2027 while (w)
2028 {
2029 ++n;
2030 w = W_NEXT(w);
2031 }
2032
2033 return n;
2034}
2035
2036/*ARGSUSED*/
2037 static PyObject *
2038WinListItem(PyObject *self, int n)
2039{
2040 win_T *w;
2041
2042 for (w = firstwin; w; w = W_NEXT(w), --n)
2043 if (n == 0)
2044 return WindowNew(w);
2045
2046 PyErr_SetString(PyExc_IndexError, _("no such window"));
2047 return NULL;
2048}
2049
2050/* Current items object - Definitions
2051 */
2052
2053typedef struct
2054{
2055 PyObject_HEAD
2056}
2057CurrentObject;
2058
2059static PyTypeObject CurrentType = {
2060 PyObject_HEAD_INIT(0)
2061 0,
2062 "current data",
2063 sizeof(CurrentObject),
2064 0,
2065
2066 (destructor) 0, /* tp_dealloc, refcount==0 */
2067 (printfunc) 0, /* tp_print, print x */
2068 (getattrfunc) CurrentGetattr, /* tp_getattr, x.attr */
2069 (setattrfunc) CurrentSetattr, /* tp_setattr, x.attr=v */
2070 (cmpfunc) 0, /* tp_compare, x>y */
2071 (reprfunc) 0, /* tp_repr, `x`, print x */
2072
2073 0, /* as number */
2074 0, /* as sequence */
2075 0, /* as mapping */
2076
2077 (hashfunc) 0, /* tp_hash, dict(x) */
2078 (ternaryfunc) 0, /* tp_call, x() */
2079 (reprfunc) 0, /* tp_str, str(x) */
2080};
2081
2082/* Current items object - Implementation
2083 */
2084/*ARGSUSED*/
2085 static PyObject *
2086CurrentGetattr(PyObject *self, char *name)
2087{
2088 if (strcmp(name, "buffer") == 0)
2089 return (PyObject *)BufferNew(curbuf);
2090 else if (strcmp(name, "window") == 0)
2091 return (PyObject *)WindowNew(curwin);
2092 else if (strcmp(name, "line") == 0)
2093 return GetBufferLine(curbuf, (int)curwin->w_cursor.lnum);
2094 else if (strcmp(name, "range") == 0)
2095 return RangeNew(curbuf, RangeStart, RangeEnd);
2096 else if (strcmp(name,"__members__") == 0)
2097 return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
2098 else
2099 {
2100 PyErr_SetString(PyExc_AttributeError, name);
2101 return NULL;
2102 }
2103}
2104
2105/*ARGSUSED*/
2106 static int
2107CurrentSetattr(PyObject *self, char *name, PyObject *value)
2108{
2109 if (strcmp(name, "line") == 0)
2110 {
2111 if (SetBufferLine(curbuf, (int)curwin->w_cursor.lnum, value, NULL) == FAIL)
2112 return -1;
2113
2114 return 0;
2115 }
2116 else
2117 {
2118 PyErr_SetString(PyExc_AttributeError, name);
2119 return -1;
2120 }
2121}
2122
2123/* External interface
2124 */
2125
2126 void
2127python_buffer_free(buf_T *buf)
2128{
2129 if (buf->python_ref)
2130 {
2131 BufferObject *bp = buf->python_ref;
2132 bp->buf = INVALID_BUFFER_VALUE;
2133 buf->python_ref = NULL;
2134 }
2135}
2136
2137#if defined(FEAT_WINDOWS) || defined(PROTO)
2138 void
2139python_window_free(win_T *win)
2140{
2141 if (win->python_ref)
2142 {
2143 WindowObject *wp = win->python_ref;
2144 wp->win = INVALID_WINDOW_VALUE;
2145 win->python_ref = NULL;
2146 }
2147}
2148#endif
2149
2150static BufListObject TheBufferList =
2151{
2152 PyObject_HEAD_INIT(&BufListType)
2153};
2154
2155static WinListObject TheWindowList =
2156{
2157 PyObject_HEAD_INIT(&WinListType)
2158};
2159
2160static CurrentObject TheCurrent =
2161{
2162 PyObject_HEAD_INIT(&CurrentType)
2163};
2164
2165 static int
2166PythonMod_Init(void)
2167{
2168 PyObject *mod;
2169 PyObject *dict;
2170 static char *(argv[2]) = {"", NULL};
2171
2172 /* Fixups... */
2173 BufferType.ob_type = &PyType_Type;
2174 RangeType.ob_type = &PyType_Type;
2175 WindowType.ob_type = &PyType_Type;
2176 BufListType.ob_type = &PyType_Type;
2177 WinListType.ob_type = &PyType_Type;
2178 CurrentType.ob_type = &PyType_Type;
2179
2180 /* Set sys.argv[] to avoid a crash in warn(). */
2181 PySys_SetArgv(1, argv);
2182
2183 mod = Py_InitModule("vim", VimMethods);
2184 dict = PyModule_GetDict(mod);
2185
2186 VimError = Py_BuildValue("s", "vim.error");
2187
2188 PyDict_SetItemString(dict, "error", VimError);
2189 PyDict_SetItemString(dict, "buffers", (PyObject *)(&TheBufferList));
2190 PyDict_SetItemString(dict, "current", (PyObject *)(&TheCurrent));
2191 PyDict_SetItemString(dict, "windows", (PyObject *)(&TheWindowList));
2192
2193 if (PyErr_Occurred())
2194 return -1;
2195
2196 return 0;
2197}
2198
2199/*************************************************************************
2200 * 4. Utility functions for handling the interface between Vim and Python.
2201 */
2202
2203/* Get a line from the specified buffer. The line number is
2204 * in Vim format (1-based). The line is returned as a Python
2205 * string object.
2206 */
2207 static PyObject *
2208GetBufferLine(buf_T *buf, int n)
2209{
2210 return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE));
2211}
2212
2213/* Get a list of lines from the specified buffer. The line numbers
2214 * are in Vim format (1-based). The range is from lo up to, but not
2215 * including, hi. The list is returned as a Python list of string objects.
2216 */
2217 static PyObject *
2218GetBufferLineList(buf_T *buf, int lo, int hi)
2219{
2220 int i;
2221 int n = hi - lo;
2222 PyObject *list = PyList_New(n);
2223
2224 if (list == NULL)
2225 return NULL;
2226
2227 for (i = 0; i < n; ++i)
2228 {
2229 PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE));
2230
2231 /* Error check - was the Python string creation OK? */
2232 if (str == NULL)
2233 {
2234 Py_DECREF(list);
2235 return NULL;
2236 }
2237
2238 /* Set the list item */
2239 if (PyList_SetItem(list, i, str))
2240 {
2241 Py_DECREF(str);
2242 Py_DECREF(list);
2243 return NULL;
2244 }
2245 }
2246
2247 /* The ownership of the Python list is passed to the caller (ie,
2248 * the caller should Py_DECREF() the object when it is finished
2249 * with it).
2250 */
2251
2252 return list;
2253}
2254
2255/*
2256 * Check if deleting lines made the cursor position invalid.
2257 * Changed the lines from "lo" to "hi" and added "extra" lines (negative if
2258 * deleted).
2259 */
2260 static void
2261py_fix_cursor(int lo, int hi, int extra)
2262{
2263 if (curwin->w_cursor.lnum >= lo)
2264 {
2265 /* Adjust the cursor position if it's in/after the changed
2266 * lines. */
2267 if (curwin->w_cursor.lnum >= hi)
2268 {
2269 curwin->w_cursor.lnum += extra;
2270 check_cursor_col();
2271 }
2272 else if (extra < 0)
2273 {
2274 curwin->w_cursor.lnum = lo;
2275 check_cursor();
2276 }
2277 changed_cline_bef_curs();
2278 }
2279 invalidate_botline();
2280}
2281
2282/* Replace a line in the specified buffer. The line number is
2283 * in Vim format (1-based). The replacement line is given as
2284 * a Python string object. The object is checked for validity
2285 * and correct format. Errors are returned as a value of FAIL.
2286 * The return value is OK on success.
2287 * If OK is returned and len_change is not NULL, *len_change
2288 * is set to the change in the buffer length.
2289 */
2290 static int
2291SetBufferLine(buf_T *buf, int n, PyObject *line, int *len_change)
2292{
2293 /* First of all, we check the thpe of the supplied Python object.
2294 * There are three cases:
2295 * 1. NULL, or None - this is a deletion.
2296 * 2. A string - this is a replacement.
2297 * 3. Anything else - this is an error.
2298 */
2299 if (line == Py_None || line == NULL)
2300 {
2301 buf_T *savebuf = curbuf;
2302
2303 PyErr_Clear();
2304 curbuf = buf;
2305
2306 if (u_savedel((linenr_T)n, 1L) == FAIL)
2307 PyErr_SetVim(_("cannot save undo information"));
2308 else if (ml_delete((linenr_T)n, FALSE) == FAIL)
2309 PyErr_SetVim(_("cannot delete line"));
2310 else
2311 {
2312 deleted_lines_mark((linenr_T)n, 1L);
2313 if (buf == curwin->w_buffer)
2314 py_fix_cursor(n, n + 1, -1);
2315 }
2316
2317 curbuf = savebuf;
2318
2319 if (PyErr_Occurred() || VimErrorCheck())
2320 return FAIL;
2321
2322 if (len_change)
2323 *len_change = -1;
2324
2325 return OK;
2326 }
2327 else if (PyString_Check(line))
2328 {
2329 char *save = StringToLine(line);
2330 buf_T *savebuf = curbuf;
2331
2332 if (save == NULL)
2333 return FAIL;
2334
2335 /* We do not need to free "save" if ml_replace() consumes it. */
2336 PyErr_Clear();
2337 curbuf = buf;
2338
2339 if (u_savesub((linenr_T)n) == FAIL)
2340 {
2341 PyErr_SetVim(_("cannot save undo information"));
2342 vim_free(save);
2343 }
2344 else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL)
2345 {
2346 PyErr_SetVim(_("cannot replace line"));
2347 vim_free(save);
2348 }
2349 else
2350 changed_bytes((linenr_T)n, 0);
2351
2352 curbuf = savebuf;
2353
2354 if (PyErr_Occurred() || VimErrorCheck())
2355 return FAIL;
2356
2357 if (len_change)
2358 *len_change = 0;
2359
2360 return OK;
2361 }
2362 else
2363 {
2364 PyErr_BadArgument();
2365 return FAIL;
2366 }
2367}
2368
2369/* Replace a range of lines in the specified buffer. The line numbers are in
2370 * Vim format (1-based). The range is from lo up to, but not including, hi.
2371 * The replacement lines are given as a Python list of string objects. The
2372 * list is checked for validity and correct format. Errors are returned as a
2373 * value of FAIL. The return value is OK on success.
2374 * If OK is returned and len_change is not NULL, *len_change
2375 * is set to the change in the buffer length.
2376 */
2377 static int
2378SetBufferLineList(buf_T *buf, int lo, int hi, PyObject *list, int *len_change)
2379{
2380 /* First of all, we check the thpe of the supplied Python object.
2381 * There are three cases:
2382 * 1. NULL, or None - this is a deletion.
2383 * 2. A list - this is a replacement.
2384 * 3. Anything else - this is an error.
2385 */
2386 if (list == Py_None || list == NULL)
2387 {
2388 int i;
2389 int n = hi - lo;
2390 buf_T *savebuf = curbuf;
2391
2392 PyErr_Clear();
2393 curbuf = buf;
2394
2395 if (u_savedel((linenr_T)lo, (long)n) == FAIL)
2396 PyErr_SetVim(_("cannot save undo information"));
2397 else
2398 {
2399 for (i = 0; i < n; ++i)
2400 {
2401 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2402 {
2403 PyErr_SetVim(_("cannot delete line"));
2404 break;
2405 }
2406 }
2407 deleted_lines_mark((linenr_T)lo, (long)i);
2408
2409 if (buf == curwin->w_buffer)
2410 py_fix_cursor(lo, hi, -n);
2411 }
2412
2413 curbuf = savebuf;
2414
2415 if (PyErr_Occurred() || VimErrorCheck())
2416 return FAIL;
2417
2418 if (len_change)
2419 *len_change = -n;
2420
2421 return OK;
2422 }
2423 else if (PyList_Check(list))
2424 {
2425 int i;
2426 int new_len = PyList_Size(list);
2427 int old_len = hi - lo;
2428 int extra = 0; /* lines added to text, can be negative */
2429 char **array;
2430 buf_T *savebuf;
2431
2432 if (new_len == 0) /* avoid allocating zero bytes */
2433 array = NULL;
2434 else
2435 {
2436 array = (char **)alloc((unsigned)(new_len * sizeof(char *)));
2437 if (array == NULL)
2438 {
2439 PyErr_NoMemory();
2440 return FAIL;
2441 }
2442 }
2443
2444 for (i = 0; i < new_len; ++i)
2445 {
2446 PyObject *line = PyList_GetItem(list, i);
2447
2448 array[i] = StringToLine(line);
2449 if (array[i] == NULL)
2450 {
2451 while (i)
2452 vim_free(array[--i]);
2453 vim_free(array);
2454 return FAIL;
2455 }
2456 }
2457
2458 savebuf = curbuf;
2459
2460 PyErr_Clear();
2461 curbuf = buf;
2462
2463 if (u_save((linenr_T)(lo-1), (linenr_T)hi) == FAIL)
2464 PyErr_SetVim(_("cannot save undo information"));
2465
2466 /* If the size of the range is reducing (ie, new_len < old_len) we
2467 * need to delete some old_len. We do this at the start, by
2468 * repeatedly deleting line "lo".
2469 */
2470 if (!PyErr_Occurred())
2471 {
2472 for (i = 0; i < old_len - new_len; ++i)
2473 if (ml_delete((linenr_T)lo, FALSE) == FAIL)
2474 {
2475 PyErr_SetVim(_("cannot delete line"));
2476 break;
2477 }
2478 extra -= i;
2479 }
2480
2481 /* For as long as possible, replace the existing old_len with the
2482 * new old_len. This is a more efficient operation, as it requires
2483 * less memory allocation and freeing.
2484 */
2485 if (!PyErr_Occurred())
2486 {
2487 for (i = 0; i < old_len && i < new_len; ++i)
2488 if (ml_replace((linenr_T)(lo+i), (char_u *)array[i], FALSE)
2489 == FAIL)
2490 {
2491 PyErr_SetVim(_("cannot replace line"));
2492 break;
2493 }
2494 }
2495 else
2496 i = 0;
2497
2498 /* Now we may need to insert the remaining new old_len. If we do, we
2499 * must free the strings as we finish with them (we can't pass the
2500 * responsibility to vim in this case).
2501 */
2502 if (!PyErr_Occurred())
2503 {
2504 while (i < new_len)
2505 {
2506 if (ml_append((linenr_T)(lo + i - 1),
2507 (char_u *)array[i], 0, FALSE) == FAIL)
2508 {
2509 PyErr_SetVim(_("cannot insert line"));
2510 break;
2511 }
2512 vim_free(array[i]);
2513 ++i;
2514 ++extra;
2515 }
2516 }
2517
2518 /* Free any left-over old_len, as a result of an error */
2519 while (i < new_len)
2520 {
2521 vim_free(array[i]);
2522 ++i;
2523 }
2524
2525 /* Free the array of old_len. All of its contents have now
2526 * been dealt with (either freed, or the responsibility passed
2527 * to vim.
2528 */
2529 vim_free(array);
2530
2531 /* Adjust marks. Invalidate any which lie in the
2532 * changed range, and move any in the remainder of the buffer.
2533 */
2534 mark_adjust((linenr_T)lo, (linenr_T)(hi - 1),
2535 (long)MAXLNUM, (long)extra);
2536 changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra);
2537
2538 if (buf == curwin->w_buffer)
2539 py_fix_cursor(lo, hi, extra);
2540
2541 curbuf = savebuf;
2542
2543 if (PyErr_Occurred() || VimErrorCheck())
2544 return FAIL;
2545
2546 if (len_change)
2547 *len_change = new_len - old_len;
2548
2549 return OK;
2550 }
2551 else
2552 {
2553 PyErr_BadArgument();
2554 return FAIL;
2555 }
2556}
2557
2558/* Insert a number of lines into the specified buffer after the specifed line.
2559 * The line number is in Vim format (1-based). The lines to be inserted are
2560 * given as a Python list of string objects or as a single string. The lines
2561 * to be added are checked for validity and correct format. Errors are
2562 * returned as a value of FAIL. The return value is OK on success.
2563 * If OK is returned and len_change is not NULL, *len_change
2564 * is set to the change in the buffer length.
2565 */
2566 static int
2567InsertBufferLines(buf_T *buf, int n, PyObject *lines, int *len_change)
2568{
2569 /* First of all, we check the type of the supplied Python object.
2570 * It must be a string or a list, or the call is in error.
2571 */
2572 if (PyString_Check(lines))
2573 {
2574 char *str = StringToLine(lines);
2575 buf_T *savebuf;
2576
2577 if (str == NULL)
2578 return FAIL;
2579
2580 savebuf = curbuf;
2581
2582 PyErr_Clear();
2583 curbuf = buf;
2584
2585 if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL)
2586 PyErr_SetVim(_("cannot save undo information"));
2587 else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL)
2588 PyErr_SetVim(_("cannot insert line"));
2589 else
2590 appended_lines_mark((linenr_T)n, 1L);
2591
2592 vim_free(str);
2593 curbuf = savebuf;
2594 update_screen(VALID);
2595
2596 if (PyErr_Occurred() || VimErrorCheck())
2597 return FAIL;
2598
2599 if (len_change)
2600 *len_change = 1;
2601
2602 return OK;
2603 }
2604 else if (PyList_Check(lines))
2605 {
2606 int i;
2607 int size = PyList_Size(lines);
2608 char **array;
2609 buf_T *savebuf;
2610
2611 array = (char **)alloc((unsigned)(size * sizeof(char *)));
2612 if (array == NULL)
2613 {
2614 PyErr_NoMemory();
2615 return FAIL;
2616 }
2617
2618 for (i = 0; i < size; ++i)
2619 {
2620 PyObject *line = PyList_GetItem(lines, i);
2621 array[i] = StringToLine(line);
2622
2623 if (array[i] == NULL)
2624 {
2625 while (i)
2626 vim_free(array[--i]);
2627 vim_free(array);
2628 return FAIL;
2629 }
2630 }
2631
2632 savebuf = curbuf;
2633
2634 PyErr_Clear();
2635 curbuf = buf;
2636
2637 if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL)
2638 PyErr_SetVim(_("cannot save undo information"));
2639 else
2640 {
2641 for (i = 0; i < size; ++i)
2642 {
2643 if (ml_append((linenr_T)(n + i),
2644 (char_u *)array[i], 0, FALSE) == FAIL)
2645 {
2646 PyErr_SetVim(_("cannot insert line"));
2647
2648 /* Free the rest of the lines */
2649 while (i < size)
2650 vim_free(array[i++]);
2651
2652 break;
2653 }
2654 vim_free(array[i]);
2655 }
2656 if (i > 0)
2657 appended_lines_mark((linenr_T)n, (long)i);
2658 }
2659
2660 /* Free the array of lines. All of its contents have now
2661 * been freed.
2662 */
2663 vim_free(array);
2664
2665 curbuf = savebuf;
2666 update_screen(VALID);
2667
2668 if (PyErr_Occurred() || VimErrorCheck())
2669 return FAIL;
2670
2671 if (len_change)
2672 *len_change = size;
2673
2674 return OK;
2675 }
2676 else
2677 {
2678 PyErr_BadArgument();
2679 return FAIL;
2680 }
2681}
2682
2683/* Convert a Vim line into a Python string.
2684 * All internal newlines are replaced by null characters.
2685 *
2686 * On errors, the Python exception data is set, and NULL is returned.
2687 */
2688 static PyObject *
2689LineToString(const char *str)
2690{
2691 PyObject *result;
2692 int len = strlen(str);
2693 char *p;
2694
2695 /* Allocate an Python string object, with uninitialised contents. We
2696 * must do it this way, so that we can modify the string in place
2697 * later. See the Python source, Objects/stringobject.c for details.
2698 */
2699 result = PyString_FromStringAndSize(NULL, len);
2700 if (result == NULL)
2701 return NULL;
2702
2703 p = PyString_AsString(result);
2704
2705 while (*str)
2706 {
2707 if (*str == '\n')
2708 *p = '\0';
2709 else
2710 *p = *str;
2711
2712 ++p;
2713 ++str;
2714 }
2715
2716 return result;
2717}
2718
2719/* Convert a Python string into a Vim line.
2720 *
2721 * The result is in allocated memory. All internal nulls are replaced by
2722 * newline characters. It is an error for the string to contain newline
2723 * characters.
2724 *
2725 * On errors, the Python exception data is set, and NULL is returned.
2726 */
2727 static char *
2728StringToLine(PyObject *obj)
2729{
2730 const char *str;
2731 char *save;
2732 int len;
2733 int i;
2734
2735 if (obj == NULL || !PyString_Check(obj))
2736 {
2737 PyErr_BadArgument();
2738 return NULL;
2739 }
2740
2741 str = PyString_AsString(obj);
2742 len = PyString_Size(obj);
2743
2744 /* Error checking: String must not contain newlines, as we
2745 * are replacing a single line, and we must replace it with
2746 * a single line.
2747 */
2748 if (memchr(str, '\n', len))
2749 {
2750 PyErr_SetVim(_("string cannot contain newlines"));
2751 return NULL;
2752 }
2753
2754 /* Create a copy of the string, with internal nulls replaced by
2755 * newline characters, as is the vim convention.
2756 */
2757 save = (char *)alloc((unsigned)(len+1));
2758 if (save == NULL)
2759 {
2760 PyErr_NoMemory();
2761 return NULL;
2762 }
2763
2764 for (i = 0; i < len; ++i)
2765 {
2766 if (str[i] == '\0')
2767 save[i] = '\n';
2768 else
2769 save[i] = str[i];
2770 }
2771
2772 save[i] = '\0';
2773
2774 return save;
2775}
2776
2777/* Check to see whether a Vim error has been reported, or a keyboard
2778 * interrupt has been detected.
2779 */
2780 static int
2781VimErrorCheck(void)
2782{
2783 if (got_int)
2784 {
2785 PyErr_SetNone(PyExc_KeyboardInterrupt);
2786 return 1;
2787 }
2788 else if (did_emsg && !PyErr_Occurred())
2789 {
2790 PyErr_SetNone(VimError);
2791 return 1;
2792 }
2793
2794 return 0;
2795}
2796
2797
2798/* Don't generate a prototype for the next function, it generates an error on
2799 * newer Python versions. */
2800#if PYTHON_API_VERSION < 1007 /* Python 1.4 */ && !defined(PROTO)
2801
2802 char *
2803Py_GetProgramName(void)
2804{
2805 return "vim";
2806}
2807#endif /* Python 1.4 */