Mercurial > vim
diff src/if_python.c @ 2447:84d353762845 vim73
Move many more common Python items to if_py_both.c.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sat, 31 Jul 2010 19:54:14 +0200 |
parents | 76f0c4918f5c |
children | 8bc2e8390c11 |
line wrap: on
line diff
--- a/src/if_python.c +++ b/src/if_python.c @@ -390,13 +390,12 @@ python_enabled(int verbose) return python_runtime_link_init(DYNAMIC_PYTHON_DLL, verbose) == OK; } -/* Load the standard Python exceptions - don't import the symbols from the +/* + * Load the standard Python exceptions - don't import the symbols from the * DLL, as this can cause errors (importing data symbols is not reliable). */ -static void get_exceptions __ARGS((void)); - static void -get_exceptions() +get_exceptions(void) { PyObject *exmod = PyImport_ImportModule("exceptions"); PyObject *exdict = PyModule_GetDict(exmod); @@ -414,6 +413,12 @@ get_exceptions() } #endif /* DYNAMIC_PYTHON */ +static PyObject *BufferNew (buf_T *); +static PyObject *WindowNew(win_T *); +static PyObject *LineToString(const char *); + +static PyTypeObject RangeType; + /* * Include the code shared with if_python3.c */ @@ -424,7 +429,6 @@ get_exceptions() * Internal function prototypes. */ -static void DoPythonCommand(exarg_T *, const char *); static PyInt RangeStart; static PyInt RangeEnd; @@ -435,17 +439,9 @@ static int PythonMod_Init(void); /* Utility functions for the vim/python interface * ---------------------------------------------- */ -static PyObject *GetBufferLine(buf_T *, PyInt); -static PyObject *GetBufferLineList(buf_T *, PyInt, PyInt); -static int SetBufferLine(buf_T *, PyInt, PyObject *, PyInt *); static int SetBufferLineList(buf_T *, PyInt, PyInt, PyObject *, PyInt *); -static int InsertBufferLines(buf_T *, PyInt, PyObject *, PyInt *); -static PyObject *LineToString(const char *); -static char *StringToLine(PyObject *); - -#define PyErr_SetVim(str) PyErr_SetString(VimError, str) /****************************************************** * 1. Python interpreter main program. @@ -734,11 +730,6 @@ ex_pyfile(exarg_T *eap) /* Implementation functions */ -static PyObject *OutputGetattr(PyObject *, char *); -static int OutputSetattr(PyObject *, char *, PyObject *); - -/*************/ - static PyObject * OutputGetattr(PyObject *self, char *name) { @@ -786,52 +777,21 @@ PythonIO_Init(void) * 3. Implementation of the Vim module for Python */ -/* Vim module - Implementation functions - * ------------------------------------- - */ - -static PyObject *VimCommand(PyObject *, PyObject *); -static PyObject *VimEval(PyObject *, PyObject *); - /* Window type - Implementation functions * -------------------------------------- */ -typedef struct -{ - PyObject_HEAD - win_T *win; -} -WindowObject; - -#define INVALID_WINDOW_VALUE ((win_T *)(-1)) - #define WindowType_Check(obj) ((obj)->ob_type == &WindowType) -static PyObject *WindowNew(win_T *); - static void WindowDestructor(PyObject *); static PyObject *WindowGetattr(PyObject *, char *); -static int WindowSetattr(PyObject *, char *, PyObject *); -static PyObject *WindowRepr(PyObject *); /* Buffer type - Implementation functions * -------------------------------------- */ -typedef struct -{ - PyObject_HEAD - buf_T *buf; -} -BufferObject; - -#define INVALID_BUFFER_VALUE ((buf_T *)(-1)) - #define BufferType_Check(obj) ((obj)->ob_type == &BufferType) -static PyObject *BufferNew (buf_T *); - static void BufferDestructor(PyObject *); static PyObject *BufferGetattr(PyObject *, char *); static PyObject *BufferRepr(PyObject *); @@ -842,53 +802,15 @@ static PyObject *BufferSlice(PyObject *, static PyInt BufferAssItem(PyObject *, PyInt, PyObject *); static PyInt BufferAssSlice(PyObject *, PyInt, PyInt, PyObject *); -static PyObject *BufferAppend(PyObject *, PyObject *); -static PyObject *BufferMark(PyObject *, PyObject *); -static PyObject *BufferRange(PyObject *, PyObject *); - /* Line range type - Implementation functions * -------------------------------------- */ -typedef struct -{ - PyObject_HEAD - BufferObject *buf; - PyInt start; - PyInt end; -} -RangeObject; - #define RangeType_Check(obj) ((obj)->ob_type == &RangeType) -static PyObject *RangeNew(buf_T *, PyInt, PyInt); - -static void RangeDestructor(PyObject *); -static PyObject *RangeGetattr(PyObject *, char *); -static PyObject *RangeRepr(PyObject *); - -static PyInt RangeLength(PyObject *); -static PyObject *RangeItem(PyObject *, PyInt); -static PyObject *RangeSlice(PyObject *, PyInt, PyInt); static PyInt RangeAssItem(PyObject *, PyInt, PyObject *); static PyInt RangeAssSlice(PyObject *, PyInt, PyInt, PyObject *); -static PyObject *RangeAppend(PyObject *, PyObject *); - -/* Window list type - Implementation functions - * ------------------------------------------- - */ - -static PyInt WinListLength(PyObject *); -static PyObject *WinListItem(PyObject *, PyInt); - -/* Buffer list type - Implementation functions - * ------------------------------------------- - */ - -static PyInt BufListLength(PyObject *); -static PyObject *BufListItem(PyObject *, PyInt); - /* Current objects type - Implementation functions * ----------------------------------------------- */ @@ -896,286 +818,10 @@ static PyObject *BufListItem(PyObject *, static PyObject *CurrentGetattr(PyObject *, char *); static int CurrentSetattr(PyObject *, char *, PyObject *); -/* Vim module - Definitions - */ - -static struct PyMethodDef VimMethods[] = { - /* name, function, calling, documentation */ - {"command", VimCommand, 1, "Execute a Vim ex-mode command" }, - {"eval", VimEval, 1, "Evaluate an expression using Vim evaluator" }, - { NULL, NULL, 0, NULL } -}; - -/* Vim module - Implementation - */ - static PyObject * -VimCommand(PyObject *self UNUSED, PyObject *args) -{ - char *cmd; - PyObject *result; - - if (!PyArg_ParseTuple(args, "s", &cmd)) - return NULL; - - PyErr_Clear(); - - Py_BEGIN_ALLOW_THREADS - Python_Lock_Vim(); - - do_cmdline_cmd((char_u *)cmd); - update_screen(VALID); - - Python_Release_Vim(); - Py_END_ALLOW_THREADS - - if (VimErrorCheck()) - result = NULL; - else - result = Py_None; - - Py_XINCREF(result); - return result; -} - -#ifdef FEAT_EVAL -/* - * Function to translate a typval_T into a PyObject; this will recursively - * translate lists/dictionaries into their Python equivalents. - * - * The depth parameter is to avoid infinite recursion, set it to 1 when - * you call VimToPython. - */ - static PyObject * -VimToPython(typval_T *our_tv, int depth, PyObject *lookupDict) -{ - PyObject *result; - PyObject *newObj; - char ptrBuf[NUMBUFLEN]; - - /* Avoid infinite recursion */ - if (depth > 100) - { - Py_INCREF(Py_None); - result = Py_None; - return result; - } - - /* Check if we run into a recursive loop. The item must be in lookupDict - * then and we can use it again. */ - if ((our_tv->v_type == VAR_LIST && our_tv->vval.v_list != NULL) - || (our_tv->v_type == VAR_DICT && our_tv->vval.v_dict != NULL)) - { - sprintf(ptrBuf, PRINTF_DECIMAL_LONG_U, - our_tv->v_type == VAR_LIST ? (long_u)our_tv->vval.v_list - : (long_u)our_tv->vval.v_dict); - result = PyDict_GetItemString(lookupDict, ptrBuf); - if (result != NULL) - { - Py_INCREF(result); - return result; - } - } - - if (our_tv->v_type == VAR_STRING) - { - result = Py_BuildValue("s", our_tv->vval.v_string); - } - else if (our_tv->v_type == VAR_NUMBER) - { - char buf[NUMBUFLEN]; - - /* For backwards compatibility numbers are stored as strings. */ - sprintf(buf, "%ld", (long)our_tv->vval.v_number); - result = Py_BuildValue("s", buf); - } -# ifdef FEAT_FLOAT - else if (our_tv->v_type == VAR_FLOAT) - { - char buf[NUMBUFLEN]; - - sprintf(buf, "%f", our_tv->vval.v_float); - result = Py_BuildValue("s", buf); - } -# endif - else if (our_tv->v_type == VAR_LIST) - { - list_T *list = our_tv->vval.v_list; - listitem_T *curr; - - result = PyList_New(0); - - if (list != NULL) - { - PyDict_SetItemString(lookupDict, ptrBuf, result); - - for (curr = list->lv_first; curr != NULL; curr = curr->li_next) - { - newObj = VimToPython(&curr->li_tv, depth + 1, lookupDict); - PyList_Append(result, newObj); - Py_DECREF(newObj); - } - } - } - else if (our_tv->v_type == VAR_DICT) - { - result = PyDict_New(); - - if (our_tv->vval.v_dict != NULL) - { - hashtab_T *ht = &our_tv->vval.v_dict->dv_hashtab; - long_u todo = ht->ht_used; - hashitem_T *hi; - dictitem_T *di; - - PyDict_SetItemString(lookupDict, ptrBuf, result); - - for (hi = ht->ht_array; todo > 0; ++hi) - { - if (!HASHITEM_EMPTY(hi)) - { - --todo; - - di = dict_lookup(hi); - newObj = VimToPython(&di->di_tv, depth + 1, lookupDict); - PyDict_SetItemString(result, (char *)hi->hi_key, newObj); - Py_DECREF(newObj); - } - } - } - } - else - { - Py_INCREF(Py_None); - result = Py_None; - } - - return result; -} -#endif - - static PyObject * -VimEval(PyObject *self UNUSED, PyObject *args) -{ -#ifdef FEAT_EVAL - char *expr; - typval_T *our_tv; - PyObject *result; - PyObject *lookup_dict; - - if (!PyArg_ParseTuple(args, "s", &expr)) - return NULL; - - Py_BEGIN_ALLOW_THREADS - Python_Lock_Vim(); - our_tv = eval_expr((char_u *)expr, NULL); - - Python_Release_Vim(); - Py_END_ALLOW_THREADS - - if (our_tv == NULL) - { - PyErr_SetVim(_("invalid expression")); - return NULL; - } - - /* Convert the Vim type into a Python type. Create a dictionary that's - * used to check for recursive loops. */ - lookup_dict = PyDict_New(); - result = VimToPython(our_tv, 1, lookup_dict); - Py_DECREF(lookup_dict); - - - Py_BEGIN_ALLOW_THREADS - Python_Lock_Vim(); - free_tv(our_tv); - Python_Release_Vim(); - Py_END_ALLOW_THREADS - - return result; -#else - PyErr_SetVim(_("expressions disabled at compile time")); - return NULL; -#endif -} - /* Common routines for buffers and line ranges * ------------------------------------------- */ - static int -CheckBuffer(BufferObject *this) -{ - if (this->buf == INVALID_BUFFER_VALUE) - { - PyErr_SetVim(_("attempt to refer to deleted buffer")); - return -1; - } - - return 0; -} - - static PyObject * -RBItem(BufferObject *self, PyInt n, PyInt start, PyInt end) -{ - if (CheckBuffer(self)) - return NULL; - - if (n < 0 || n > end - start) - { - PyErr_SetString(PyExc_IndexError, _("line number out of range")); - return NULL; - } - - return GetBufferLine(self->buf, n+start); -} - - static PyObject * -RBSlice(BufferObject *self, PyInt lo, PyInt hi, PyInt start, PyInt end) -{ - PyInt size; - - if (CheckBuffer(self)) - return NULL; - - size = end - start + 1; - - if (lo < 0) - lo = 0; - else if (lo > size) - lo = size; - if (hi < 0) - hi = 0; - if (hi < lo) - hi = lo; - else if (hi > size) - hi = size; - - return GetBufferLineList(self->buf, lo+start, hi+start); -} - - static PyInt -RBAssItem(BufferObject *self, PyInt n, PyObject *val, PyInt start, PyInt end, PyInt *new_end) -{ - PyInt len_change; - - if (CheckBuffer(self)) - return -1; - - if (n < 0 || n > end - start) - { - PyErr_SetString(PyExc_IndexError, _("line number out of range")); - return -1; - } - - if (SetBufferLine(self->buf, n+start, val, &len_change) == FAIL) - return -1; - - if (new_end) - *new_end = end + len_change; - - return 0; -} - static PyInt RBAssSlice(BufferObject *self, PyInt lo, PyInt hi, PyObject *val, PyInt start, PyInt end, PyInt *new_end) { @@ -1200,7 +846,8 @@ RBAssSlice(BufferObject *self, PyInt lo, else if (hi > size) hi = size; - if (SetBufferLineList(self->buf, lo+start, hi+start, val, &len_change) == FAIL) + if (SetBufferLineList(self->buf, lo + start, hi + start, + val, &len_change) == FAIL) return -1; if (new_end) @@ -1209,50 +856,6 @@ RBAssSlice(BufferObject *self, PyInt lo, return 0; } - static PyObject * -RBAppend(BufferObject *self, PyObject *args, PyInt start, PyInt end, PyInt *new_end) -{ - PyObject *lines; - PyInt len_change; - PyInt max; - PyInt n; - - if (CheckBuffer(self)) - return NULL; - - max = n = end - start + 1; - - if (!PyArg_ParseTuple(args, "O|" Py_ssize_t_fmt, &lines, &n)) - return NULL; - - if (n < 0 || n > max) - { - PyErr_SetString(PyExc_ValueError, _("line number out of range")); - return NULL; - } - - if (InsertBufferLines(self->buf, n + start - 1, lines, &len_change) == FAIL) - return NULL; - - if (new_end) - *new_end = end + len_change; - - Py_INCREF(Py_None); - return Py_None; -} - - -/* Buffer object - Definitions - */ - -static struct PyMethodDef BufferMethods[] = { - /* name, function, calling, documentation */ - {"append", BufferAppend, 1, "Append data to Vim buffer" }, - {"mark", BufferMark, 1, "Return (row,col) representing position of named mark" }, - {"range", BufferRange, 1, "Return a range object which represents the part of the given buffer between line numbers s and e" }, - { NULL, NULL, 0, NULL } -}; - static PySequenceMethods BufferAsSeq = { (PyInquiry) BufferLength, /* sq_length, len(x) */ (binaryfunc) 0, /* BufferConcat, */ /* sq_concat, x+y */ @@ -1412,7 +1015,7 @@ BufferSlice(PyObject *self, PyInt lo, Py static PyInt BufferAssItem(PyObject *self, PyInt n, PyObject *val) { - return RBAssItem((BufferObject *)(self), n, val, 1, + return RBAsItem((BufferObject *)(self), n, val, 1, (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count, NULL); } @@ -1425,76 +1028,6 @@ BufferAssSlice(PyObject *self, PyInt lo, NULL); } - static PyObject * -BufferAppend(PyObject *self, PyObject *args) -{ - return RBAppend((BufferObject *)(self), args, 1, - (PyInt)((BufferObject *)(self))->buf->b_ml.ml_line_count, - NULL); -} - - static PyObject * -BufferMark(PyObject *self, PyObject *args) -{ - pos_T *posp; - char mark; - buf_T *curbuf_save; - - if (CheckBuffer((BufferObject *)(self))) - return NULL; - - if (!PyArg_ParseTuple(args, "c", &mark)) - return NULL; - - curbuf_save = curbuf; - curbuf = ((BufferObject *)(self))->buf; - posp = getmark(mark, FALSE); - curbuf = curbuf_save; - - if (posp == NULL) - { - PyErr_SetVim(_("invalid mark name")); - return NULL; - } - - /* Ckeck for keyboard interrupt */ - if (VimErrorCheck()) - return NULL; - - if (posp->lnum <= 0) - { - /* Or raise an error? */ - Py_INCREF(Py_None); - return Py_None; - } - - return Py_BuildValue("(ll)", (long)(posp->lnum), (long)(posp->col)); -} - - static PyObject * -BufferRange(PyObject *self, PyObject *args) -{ - PyInt start; - PyInt end; - - if (CheckBuffer((BufferObject *)(self))) - return NULL; - - if (!PyArg_ParseTuple(args, Py_ssize_t_fmt Py_ssize_t_fmt, &start, &end)) - return NULL; - - return RangeNew(((BufferObject *)(self))->buf, start, end); -} - -/* Line range object - Definitions - */ - -static struct PyMethodDef RangeMethods[] = { - /* name, function, calling, documentation */ - {"append", RangeAppend, 1, "Append data to the Vim range" }, - { NULL, NULL, 0, NULL } -}; - static PySequenceMethods RangeAsSeq = { (PyInquiry) RangeLength, /* sq_length, len(x) */ (binaryfunc) 0, /* RangeConcat, */ /* sq_concat, x+y */ @@ -1505,56 +1038,9 @@ static PySequenceMethods RangeAsSeq = { (PyIntIntObjArgProc) RangeAssSlice, /* sq_ass_slice, x[i:j]=v */ }; -static PyTypeObject RangeType = { - PyObject_HEAD_INIT(0) - 0, - "range", - sizeof(RangeObject), - 0, - - (destructor) RangeDestructor, /* tp_dealloc, refcount==0 */ - (printfunc) 0, /* tp_print, print x */ - (getattrfunc) RangeGetattr, /* tp_getattr, x.attr */ - (setattrfunc) 0, /* tp_setattr, x.attr=v */ - (cmpfunc) 0, /* tp_compare, x>y */ - (reprfunc) RangeRepr, /* tp_repr, `x`, print x */ - - 0, /* as number */ - &RangeAsSeq, /* as sequence */ - 0, /* as mapping */ - - (hashfunc) 0, /* tp_hash, dict(x) */ - (ternaryfunc) 0, /* tp_call, x() */ - (reprfunc) 0, /* tp_str, str(x) */ -}; - /* Line range object - Implementation */ - static PyObject * -RangeNew(buf_T *buf, PyInt start, PyInt end) -{ - BufferObject *bufr; - RangeObject *self; - self = PyObject_NEW(RangeObject, &RangeType); - if (self == NULL) - return NULL; - - bufr = (BufferObject *)BufferNew(buf); - if (bufr == NULL) - { - Py_DECREF(self); - return NULL; - } - Py_INCREF(bufr); - - self->buf = bufr; - self->start = start; - self->end = end; - - return (PyObject *)(self); -} - static void RangeDestructor(PyObject *self) { @@ -1573,70 +1059,12 @@ RangeGetattr(PyObject *self, char *name) return Py_FindMethod(RangeMethods, self, name); } - static PyObject * -RangeRepr(PyObject *self) -{ - static char repr[100]; - RangeObject *this = (RangeObject *)(self); - - if (this->buf->buf == INVALID_BUFFER_VALUE) - { - vim_snprintf(repr, 100, "<range object (for deleted buffer) at %p>", - (self)); - return PyString_FromString(repr); - } - else - { - char *name = (char *)this->buf->buf->b_fname; - int len; - - if (name == NULL) - name = ""; - len = (int)strlen(name); - - if (len > 45) - name = name + (45 - len); - - vim_snprintf(repr, 100, "<range %s%s (%d:%d)>", - len > 45 ? "..." : "", name, - this->start, this->end); - - return PyString_FromString(repr); - } -} - /****************/ static PyInt -RangeLength(PyObject *self) -{ - /* HOW DO WE SIGNAL AN ERROR FROM THIS FUNCTION? */ - if (CheckBuffer(((RangeObject *)(self))->buf)) - return -1; /* ??? */ - - return (((RangeObject *)(self))->end - ((RangeObject *)(self))->start + 1); -} - - static PyObject * -RangeItem(PyObject *self, PyInt n) -{ - return RBItem(((RangeObject *)(self))->buf, n, - ((RangeObject *)(self))->start, - ((RangeObject *)(self))->end); -} - - static PyObject * -RangeSlice(PyObject *self, PyInt lo, PyInt hi) -{ - return RBSlice(((RangeObject *)(self))->buf, lo, hi, - ((RangeObject *)(self))->start, - ((RangeObject *)(self))->end); -} - - static PyInt RangeAssItem(PyObject *self, PyInt n, PyObject *val) { - return RBAssItem(((RangeObject *)(self))->buf, n, val, + return RBAsItem(((RangeObject *)(self))->buf, n, val, ((RangeObject *)(self))->start, ((RangeObject *)(self))->end, &((RangeObject *)(self))->end); @@ -1651,23 +1079,13 @@ RangeAssSlice(PyObject *self, PyInt lo, &((RangeObject *)(self))->end); } - static PyObject * -RangeAppend(PyObject *self, PyObject *args) -{ - return RBAppend(((RangeObject *)(self))->buf, args, - ((RangeObject *)(self))->start, - ((RangeObject *)(self))->end, - &((RangeObject *)(self))->end); -} - /* Buffer list object - Definitions */ typedef struct { PyObject_HEAD -} -BufListObject; +} BufListObject; static PySequenceMethods BufListAsSeq = { (PyInquiry) BufListLength, /* sq_length, len(x) */ @@ -1702,39 +1120,6 @@ static PyTypeObject BufListType = { (reprfunc) 0, /* tp_str, str(x) */ }; -/* Buffer list object - Implementation - */ - - static PyInt -BufListLength(PyObject *self UNUSED) -{ - buf_T *b = firstbuf; - PyInt n = 0; - - while (b) - { - ++n; - b = b->b_next; - } - - return n; -} - - static PyObject * -BufListItem(PyObject *self UNUSED, PyInt n) -{ - buf_T *b; - - for (b = firstbuf; b; b = b->b_next, --n) - { - if (n == 0) - return BufferNew(b); - } - - PyErr_SetString(PyExc_IndexError, _("no such buffer")); - return NULL; -} - /* Window object - Definitions */ @@ -1814,18 +1199,6 @@ WindowDestructor(PyObject *self) Py_DECREF(self); } - static int -CheckWindow(WindowObject *this) -{ - if (this->win == INVALID_WINDOW_VALUE) - { - PyErr_SetVim(_("attempt to refer to deleted window")); - return -1; - } - - return 0; -} - static PyObject * WindowGetattr(PyObject *self, char *name) { @@ -1854,134 +1227,6 @@ WindowGetattr(PyObject *self, char *name return Py_FindMethod(WindowMethods, self, name); } - static int -WindowSetattr(PyObject *self, char *name, PyObject *val) -{ - WindowObject *this = (WindowObject *)(self); - - if (CheckWindow(this)) - return -1; - - if (strcmp(name, "buffer") == 0) - { - PyErr_SetString(PyExc_TypeError, _("readonly attribute")); - return -1; - } - else if (strcmp(name, "cursor") == 0) - { - long lnum; - long col; - long len; - - if (!PyArg_Parse(val, "(ll)", &lnum, &col)) - return -1; - - if (lnum <= 0 || lnum > this->win->w_buffer->b_ml.ml_line_count) - { - PyErr_SetVim(_("cursor position outside buffer")); - return -1; - } - - /* Check for keyboard interrupts */ - if (VimErrorCheck()) - return -1; - - /* When column is out of range silently correct it. */ - len = (long)STRLEN(ml_get_buf(this->win->w_buffer, lnum, FALSE)); - if (col > len) - col = len; - - this->win->w_cursor.lnum = lnum; - this->win->w_cursor.col = col; -#ifdef FEAT_VIRTUALEDIT - this->win->w_cursor.coladd = 0; -#endif - update_screen(VALID); - - return 0; - } - else if (strcmp(name, "height") == 0) - { - int height; - win_T *savewin; - - if (!PyArg_Parse(val, "i", &height)) - return -1; - -#ifdef FEAT_GUI - need_mouse_correct = TRUE; -#endif - savewin = curwin; - curwin = this->win; - win_setheight(height); - curwin = savewin; - - /* Check for keyboard interrupts */ - if (VimErrorCheck()) - return -1; - - return 0; - } -#ifdef FEAT_VERTSPLIT - else if (strcmp(name, "width") == 0) - { - int width; - win_T *savewin; - - if (!PyArg_Parse(val, "i", &width)) - return -1; - -#ifdef FEAT_GUI - need_mouse_correct = TRUE; -#endif - savewin = curwin; - curwin = this->win; - win_setwidth(width); - curwin = savewin; - - /* Check for keyboard interrupts */ - if (VimErrorCheck()) - return -1; - - return 0; - } -#endif - else - { - PyErr_SetString(PyExc_AttributeError, name); - return -1; - } -} - - static PyObject * -WindowRepr(PyObject *self) -{ - static char repr[100]; - WindowObject *this = (WindowObject *)(self); - - if (this->win == INVALID_WINDOW_VALUE) - { - vim_snprintf(repr, 100, _("<window object (deleted) at %p>"), (self)); - return PyString_FromString(repr); - } - else - { - int i = 0; - win_T *w; - - for (w = firstwin; w != NULL && w != this->win; w = W_NEXT(w)) - ++i; - - if (w == NULL) - vim_snprintf(repr, 100, _("<window object (unknown) at %p>"), - (self)); - else - vim_snprintf(repr, 100, _("<window %d>"), i); - - return PyString_FromString(repr); - } -} - /* Window list object - Definitions */ @@ -2024,44 +1269,13 @@ static PyTypeObject WinListType = { (reprfunc) 0, /* tp_str, str(x) */ }; -/* Window list object - Implementation - */ - static PyInt -WinListLength(PyObject *self UNUSED) -{ - win_T *w = firstwin; - PyInt n = 0; - - while (w != NULL) - { - ++n; - w = W_NEXT(w); - } - - return n; -} - - static PyObject * -WinListItem(PyObject *self UNUSED, PyInt n) -{ - win_T *w; - - for (w = firstwin; w != NULL; w = W_NEXT(w), --n) - if (n == 0) - return WindowNew(w); - - PyErr_SetString(PyExc_IndexError, _("no such window")); - return NULL; -} - /* Current items object - Definitions */ typedef struct { PyObject_HEAD -} -CurrentObject; +} CurrentObject; static PyTypeObject CurrentType = { PyObject_HEAD_INIT(0) @@ -2206,178 +1420,6 @@ PythonMod_Init(void) * 4. Utility functions for handling the interface between Vim and Python. */ -/* Get a line from the specified buffer. The line number is - * in Vim format (1-based). The line is returned as a Python - * string object. - */ - static PyObject * -GetBufferLine(buf_T *buf, PyInt n) -{ - return LineToString((char *)ml_get_buf(buf, (linenr_T)n, FALSE)); -} - -/* Get a list of lines from the specified buffer. The line numbers - * are in Vim format (1-based). The range is from lo up to, but not - * including, hi. The list is returned as a Python list of string objects. - */ - static PyObject * -GetBufferLineList(buf_T *buf, PyInt lo, PyInt hi) -{ - PyInt i; - PyInt n = hi - lo; - PyObject *list = PyList_New(n); - - if (list == NULL) - return NULL; - - for (i = 0; i < n; ++i) - { - PyObject *str = LineToString((char *)ml_get_buf(buf, (linenr_T)(lo+i), FALSE)); - - /* Error check - was the Python string creation OK? */ - if (str == NULL) - { - Py_DECREF(list); - return NULL; - } - - /* Set the list item */ - if (PyList_SetItem(list, i, str)) - { - Py_DECREF(str); - Py_DECREF(list); - return NULL; - } - } - - /* The ownership of the Python list is passed to the caller (ie, - * the caller should Py_DECREF() the object when it is finished - * with it). - */ - - return list; -} - -/* - * Check if deleting lines made the cursor position invalid. - * Changed the lines from "lo" to "hi" and added "extra" lines (negative if - * deleted). - */ - static void -py_fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra) -{ - if (curwin->w_cursor.lnum >= lo) - { - /* Adjust the cursor position if it's in/after the changed - * lines. */ - if (curwin->w_cursor.lnum >= hi) - { - curwin->w_cursor.lnum += extra; - check_cursor_col(); - } - else if (extra < 0) - { - curwin->w_cursor.lnum = lo; - check_cursor(); - } - else - check_cursor_col(); - changed_cline_bef_curs(); - } - invalidate_botline(); -} - -/* Replace a line in the specified buffer. The line number is - * in Vim format (1-based). The replacement line is given as - * a Python string object. The object is checked for validity - * and correct format. Errors are returned as a value of FAIL. - * The return value is OK on success. - * If OK is returned and len_change is not NULL, *len_change - * is set to the change in the buffer length. - */ - static int -SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) -{ - /* First of all, we check the thpe of the supplied Python object. - * There are three cases: - * 1. NULL, or None - this is a deletion. - * 2. A string - this is a replacement. - * 3. Anything else - this is an error. - */ - if (line == Py_None || line == NULL) - { - buf_T *savebuf = curbuf; - - PyErr_Clear(); - curbuf = buf; - - if (u_savedel((linenr_T)n, 1L) == FAIL) - PyErr_SetVim(_("cannot save undo information")); - else if (ml_delete((linenr_T)n, FALSE) == FAIL) - PyErr_SetVim(_("cannot delete line")); - else - { - if (buf == curwin->w_buffer) - py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1); - deleted_lines_mark((linenr_T)n, 1L); - } - - curbuf = savebuf; - - if (PyErr_Occurred() || VimErrorCheck()) - return FAIL; - - if (len_change) - *len_change = -1; - - return OK; - } - else if (PyString_Check(line)) - { - char *save = StringToLine(line); - buf_T *savebuf = curbuf; - - if (save == NULL) - return FAIL; - - /* We do not need to free "save" if ml_replace() consumes it. */ - PyErr_Clear(); - curbuf = buf; - - if (u_savesub((linenr_T)n) == FAIL) - { - PyErr_SetVim(_("cannot save undo information")); - vim_free(save); - } - else if (ml_replace((linenr_T)n, (char_u *)save, FALSE) == FAIL) - { - PyErr_SetVim(_("cannot replace line")); - vim_free(save); - } - else - changed_bytes((linenr_T)n, 0); - - curbuf = savebuf; - - /* Check that the cursor is not beyond the end of the line now. */ - if (buf == curwin->w_buffer) - check_cursor_col(); - - if (PyErr_Occurred() || VimErrorCheck()) - return FAIL; - - if (len_change) - *len_change = 0; - - return OK; - } - else - { - PyErr_BadArgument(); - return FAIL; - } -} - /* Replace a range of lines in the specified buffer. The line numbers are in * Vim format (1-based). The range is from lo up to, but not including, hi. * The replacement lines are given as a Python list of string objects. The @@ -2566,131 +1608,6 @@ SetBufferLineList(buf_T *buf, PyInt lo, } } -/* Insert a number of lines into the specified buffer after the specifed line. - * The line number is in Vim format (1-based). The lines to be inserted are - * given as a Python list of string objects or as a single string. The lines - * to be added are checked for validity and correct format. Errors are - * returned as a value of FAIL. The return value is OK on success. - * If OK is returned and len_change is not NULL, *len_change - * is set to the change in the buffer length. - */ - static int -InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) -{ - /* First of all, we check the type of the supplied Python object. - * It must be a string or a list, or the call is in error. - */ - if (PyString_Check(lines)) - { - char *str = StringToLine(lines); - buf_T *savebuf; - - if (str == NULL) - return FAIL; - - savebuf = curbuf; - - PyErr_Clear(); - curbuf = buf; - - if (u_save((linenr_T)n, (linenr_T)(n+1)) == FAIL) - PyErr_SetVim(_("cannot save undo information")); - else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL) - PyErr_SetVim(_("cannot insert line")); - else - appended_lines_mark((linenr_T)n, 1L); - - vim_free(str); - curbuf = savebuf; - update_screen(VALID); - - if (PyErr_Occurred() || VimErrorCheck()) - return FAIL; - - if (len_change) - *len_change = 1; - - return OK; - } - else if (PyList_Check(lines)) - { - PyInt i; - PyInt size = PyList_Size(lines); - char **array; - buf_T *savebuf; - - array = (char **)alloc((unsigned)(size * sizeof(char *))); - if (array == NULL) - { - PyErr_NoMemory(); - return FAIL; - } - - for (i = 0; i < size; ++i) - { - PyObject *line = PyList_GetItem(lines, i); - array[i] = StringToLine(line); - - if (array[i] == NULL) - { - while (i) - vim_free(array[--i]); - vim_free(array); - return FAIL; - } - } - - savebuf = curbuf; - - PyErr_Clear(); - curbuf = buf; - - if (u_save((linenr_T)n, (linenr_T)(n + 1)) == FAIL) - PyErr_SetVim(_("cannot save undo information")); - else - { - for (i = 0; i < size; ++i) - { - if (ml_append((linenr_T)(n + i), - (char_u *)array[i], 0, FALSE) == FAIL) - { - PyErr_SetVim(_("cannot insert line")); - - /* Free the rest of the lines */ - while (i < size) - vim_free(array[i++]); - - break; - } - vim_free(array[i]); - } - if (i > 0) - appended_lines_mark((linenr_T)n, (long)i); - } - - /* Free the array of lines. All of its contents have now - * been freed. - */ - vim_free(array); - - curbuf = savebuf; - update_screen(VALID); - - if (PyErr_Occurred() || VimErrorCheck()) - return FAIL; - - if (len_change) - *len_change = size; - - return OK; - } - else - { - PyErr_BadArgument(); - return FAIL; - } -} - /* Convert a Vim line into a Python string. * All internal newlines are replaced by null characters. * @@ -2727,73 +1644,6 @@ LineToString(const char *str) return result; } -/* Convert a Python string into a Vim line. - * - * The result is in allocated memory. All internal nulls are replaced by - * newline characters. It is an error for the string to contain newline - * characters. - * - * On errors, the Python exception data is set, and NULL is returned. - */ - static char * -StringToLine(PyObject *obj) -{ - const char *str; - char *save; - PyInt len; - PyInt i; - char *p; - - if (obj == NULL || !PyString_Check(obj)) - { - PyErr_BadArgument(); - return NULL; - } - - str = PyString_AsString(obj); - len = PyString_Size(obj); - - /* - * Error checking: String must not contain newlines, as we - * are replacing a single line, and we must replace it with - * a single line. - * A trailing newline is removed, so that append(f.readlines()) works. - */ - p = memchr(str, '\n', len); - if (p != NULL) - { - if (p == str + len - 1) - --len; - else - { - PyErr_SetVim(_("string cannot contain newlines")); - return NULL; - } - } - - /* Create a copy of the string, with internal nulls replaced by - * newline characters, as is the vim convention. - */ - save = (char *)alloc((unsigned)(len+1)); - if (save == NULL) - { - PyErr_NoMemory(); - return NULL; - } - - for (i = 0; i < len; ++i) - { - if (str[i] == '\0') - save[i] = '\n'; - else - save[i] = str[i]; - } - - save[i] = '\0'; - - return save; -} - /* Don't generate a prototype for the next function, it generates an error on * newer Python versions. */ @@ -2814,4 +1664,12 @@ init_structs(void) OutputType.tp_basicsize = sizeof(OutputObject); OutputType.tp_getattr = OutputGetattr; OutputType.tp_setattr = OutputSetattr; + + vim_memset(&RangeType, 0, sizeof(RangeType)); + RangeType.tp_name = "range"; + RangeType.tp_basicsize = sizeof(RangeObject); + RangeType.tp_dealloc = RangeDestructor; + RangeType.tp_getattr = RangeGetattr; + RangeType.tp_repr = RangeRepr; + RangeType.tp_as_sequence = &RangeAsSeq; }