Compare commits

...

3 Commits

Author SHA1 Message Date
Bram Moolenaar
1028f4d75e updated for version 7.4.152
Problem:    Python: Cannot iterate over options.
Solution:   Add options iterator. (ZyX)
2014-01-14 16:55:00 +01:00
Bram Moolenaar
063a46ba77 updated for version 7.4.151
Problem:    Python: slices with steps are not supported.
Solution:   Support slices in Python vim.List. (ZyX)
2014-01-14 16:36:51 +01:00
Bram Moolenaar
14177b77bf updated for version 7.4.150
Problem:    :keeppatterns is not respected for :s.
Solution:   Check the keeppatterns flag. (Yasuhiro Matsumoto)
2014-01-14 15:53:51 +01:00
16 changed files with 894 additions and 275 deletions

View File

@@ -6425,6 +6425,16 @@ list_insert_tv(l, tv, item)
if (ni == NULL)
return FAIL;
copy_tv(tv, &ni->li_tv);
list_insert(l, ni, item);
return OK;
}
void
list_insert(l, ni, item)
list_T *l;
listitem_T *ni;
listitem_T *item;
{
if (item == NULL)
/* Append new item at end of list. */
list_append(l, ni);
@@ -6446,7 +6456,6 @@ list_insert_tv(l, tv, item)
item->li_prev = ni;
++l->lv_len;
}
return OK;
}
/*

View File

@@ -36,8 +36,9 @@ static const char *vim_special_path = "_vim_path_";
#define PyErr_SET_STRING(exc, str) PyErr_SetString(exc, _(str))
#define PyErr_SetVim(str) PyErr_SetString(VimError, str)
#define PyErr_SET_VIM(str) PyErr_SET_STRING(VimError, str)
#define PyErr_FORMAT(exc, str, tail) PyErr_Format(exc, _(str), tail)
#define PyErr_VIM_FORMAT(str, tail) PyErr_FORMAT(VimError, str, tail)
#define PyErr_FORMAT(exc, str, arg) PyErr_Format(exc, _(str), arg)
#define PyErr_FORMAT2(exc, str, arg1, arg2) PyErr_Format(exc, _(str), arg1,arg2)
#define PyErr_VIM_FORMAT(str, arg) PyErr_FORMAT(VimError, str, arg)
#define Py_TYPE_NAME(obj) (obj->ob_type->tp_name == NULL \
? "(NULL)" \
@@ -2108,8 +2109,6 @@ static struct PyMethodDef DictionaryMethods[] = {
};
static PyTypeObject ListType;
static PySequenceMethods ListAsSeq;
static PyMappingMethods ListAsMapping;
typedef struct
{
@@ -2253,7 +2252,7 @@ ListLength(ListObject *self)
}
static PyObject *
ListItem(ListObject *self, Py_ssize_t index)
ListIndex(ListObject *self, Py_ssize_t index)
{
listitem_T *li;
@@ -2273,53 +2272,389 @@ ListItem(ListObject *self, Py_ssize_t index)
return ConvertToPyObject(&li->li_tv);
}
#define PROC_RANGE \
if (last < 0) {\
if (last < -size) \
last = 0; \
else \
last += size; \
} \
if (first < 0) \
first = 0; \
if (first > size) \
first = size; \
if (last > size) \
last = size;
static PyObject *
ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last)
ListSlice(ListObject *self, Py_ssize_t first, Py_ssize_t step,
Py_ssize_t slicelen)
{
PyInt i;
PyInt size = ListLength(self);
PyInt n;
PyObject *list;
int reversed = 0;
PROC_RANGE
if (first >= last)
first = last;
if (step == 0)
{
PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
return NULL;
}
n = last-first;
list = PyList_New(n);
list = PyList_New(slicelen);
if (list == NULL)
return NULL;
for (i = 0; i < n; ++i)
for (i = 0; i < slicelen; ++i)
{
PyObject *item = ListItem(self, first + i);
PyObject *item;
item = ListIndex(self, first + i*step);
if (item == NULL)
{
Py_DECREF(list);
return NULL;
}
PyList_SET_ITEM(list, ((reversed)?(n-i-1):(i)), item);
PyList_SET_ITEM(list, i, item);
}
return list;
}
static PyObject *
ListItem(ListObject *self, PyObject* idx)
{
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(idx))
{
long _idx = PyInt_AsLong(idx);
return ListIndex(self, _idx);
}
else
#endif
if (PyLong_Check(idx))
{
long _idx = PyLong_AsLong(idx);
return ListIndex(self, _idx);
}
else if (PySlice_Check(idx))
{
Py_ssize_t start, stop, step, slicelen;
if (PySlice_GetIndicesEx(idx, ListLength(self),
&start, &stop, &step, &slicelen) < 0)
return NULL;
return ListSlice(self, start, step, slicelen);
}
else
{
RAISE_INVALID_INDEX_TYPE(idx);
return NULL;
}
}
static void
list_restore(Py_ssize_t numadded, Py_ssize_t numreplaced, Py_ssize_t slicelen,
list_T *l, listitem_T **lis, listitem_T *lastaddedli)
{
while (numreplaced--)
{
list_insert(l, lis[numreplaced], lis[slicelen + numreplaced]);
listitem_remove(l, lis[slicelen + numreplaced]);
}
while (numadded--)
{
listitem_T *next;
next = lastaddedli->li_prev;
listitem_remove(l, lastaddedli);
lastaddedli = next;
}
}
static int
ListAssSlice(ListObject *self, Py_ssize_t first,
Py_ssize_t step, Py_ssize_t slicelen, PyObject *obj)
{
PyObject *iterator;
PyObject *item;
listitem_T *li;
listitem_T *lastaddedli = NULL;
listitem_T *next;
typval_T v;
list_T *l = self->list;
PyInt i;
PyInt j;
PyInt numreplaced = 0;
PyInt numadded = 0;
PyInt size;
listitem_T **lis;
size = ListLength(self);
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return -1;
}
if (step == 0)
{
PyErr_SET_STRING(PyExc_ValueError, N_("slice step cannot be zero"));
return -1;
}
if (step != 1 && slicelen == 0)
{
/* Nothing to do. Only error out if obj has some items. */
int ret = 0;
if (obj == NULL)
return 0;
if (!(iterator = PyObject_GetIter(obj)))
return -1;
if ((item = PyIter_Next(iterator)))
{
PyErr_FORMAT(PyExc_ValueError,
N_("attempt to assign sequence of size greater then %d "
"to extended slice"), 0);
Py_DECREF(item);
ret = -1;
}
Py_DECREF(iterator);
return ret;
}
if (obj != NULL)
/* XXX May allocate zero bytes. */
if (!(lis = PyMem_New(listitem_T *, slicelen * 2)))
{
PyErr_NoMemory();
return -1;
}
if (first == size)
li = NULL;
else
{
li = list_find(l, (long) first);
if (li == NULL)
{
PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
(int)first);
if (obj != NULL)
PyMem_Free(lis);
return -1;
}
i = slicelen;
while (i-- && li != NULL)
{
j = step;
next = li;
if (step > 0)
while (next != NULL && ((next = next->li_next) != NULL) && --j);
else
while (next != NULL && ((next = next->li_prev) != NULL) && ++j);
if (obj == NULL)
listitem_remove(l, li);
else
lis[slicelen - i - 1] = li;
li = next;
}
if (li == NULL && i != -1)
{
PyErr_SET_VIM(N_("internal error: not enough list items"));
if (obj != NULL)
PyMem_Free(lis);
return -1;
}
}
if (obj == NULL)
return 0;
if (!(iterator = PyObject_GetIter(obj)))
{
PyMem_Free(lis);
return -1;
}
i = 0;
while ((item = PyIter_Next(iterator)))
{
if (ConvertFromPyObject(item, &v) == -1)
{
Py_DECREF(iterator);
Py_DECREF(item);
PyMem_Free(lis);
return -1;
}
Py_DECREF(item);
if (list_insert_tv(l, &v, numreplaced < slicelen
? lis[numreplaced]
: li) == FAIL)
{
clear_tv(&v);
PyErr_SET_VIM(N_("internal error: failed to add item to list"));
list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
PyMem_Free(lis);
return -1;
}
if (numreplaced < slicelen)
{
lis[slicelen + numreplaced] = lis[numreplaced]->li_prev;
list_remove(l, lis[numreplaced], lis[numreplaced]);
numreplaced++;
}
else
{
if (li)
lastaddedli = li->li_prev;
else
lastaddedli = l->lv_last;
numadded++;
}
clear_tv(&v);
if (step != 1 && i >= slicelen)
{
Py_DECREF(iterator);
PyErr_FORMAT(PyExc_ValueError,
N_("attempt to assign sequence of size greater then %d "
"to extended slice"), slicelen);
list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
PyMem_Free(lis);
return -1;
}
++i;
}
Py_DECREF(iterator);
if (step != 1 && i != slicelen)
{
PyErr_FORMAT2(PyExc_ValueError,
N_("attempt to assign sequence of size %d to extended slice "
"of size %d"), i, slicelen);
list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
PyMem_Free(lis);
return -1;
}
if (PyErr_Occurred())
{
list_restore(numadded, numreplaced, slicelen, l, lis, lastaddedli);
PyMem_Free(lis);
return -1;
}
for (i = 0; i < numreplaced; i++)
listitem_free(lis[i]);
if (step == 1)
for (i = numreplaced; i < slicelen; i++)
listitem_remove(l, lis[i]);
PyMem_Free(lis);
return 0;
}
static int
ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
{
typval_T tv;
list_T *l = self->list;
listitem_T *li;
Py_ssize_t length = ListLength(self);
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return -1;
}
if (index > length || (index == length && obj == NULL))
{
PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
return -1;
}
if (obj == NULL)
{
li = list_find(l, (long) index);
list_remove(l, li, li);
clear_tv(&li->li_tv);
vim_free(li);
return 0;
}
if (ConvertFromPyObject(obj, &tv) == -1)
return -1;
if (index == length)
{
if (list_append_tv(l, &tv) == FAIL)
{
clear_tv(&tv);
PyErr_SET_VIM(N_("failed to add item to list"));
return -1;
}
}
else
{
li = list_find(l, (long) index);
clear_tv(&li->li_tv);
copy_tv(&tv, &li->li_tv);
clear_tv(&tv);
}
return 0;
}
static Py_ssize_t
ListAssItem(ListObject *self, PyObject *idx, PyObject *obj)
{
#if PY_MAJOR_VERSION < 3
if (PyInt_Check(idx))
{
long _idx = PyInt_AsLong(idx);
return ListAssIndex(self, _idx, obj);
}
else
#endif
if (PyLong_Check(idx))
{
long _idx = PyLong_AsLong(idx);
return ListAssIndex(self, _idx, obj);
}
else if (PySlice_Check(idx))
{
Py_ssize_t start, stop, step, slicelen;
if (PySlice_GetIndicesEx(idx, ListLength(self),
&start, &stop, &step, &slicelen) < 0)
return -1;
return ListAssSlice(self, start, step, slicelen,
obj);
}
else
{
RAISE_INVALID_INDEX_TYPE(idx);
return -1;
}
}
static PyObject *
ListConcatInPlace(ListObject *self, PyObject *obj)
{
list_T *l = self->list;
PyObject *lookup_dict;
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return NULL;
}
if (!(lookup_dict = PyDict_New()))
return NULL;
if (list_py_concat(l, obj, lookup_dict) == -1)
{
Py_DECREF(lookup_dict);
return NULL;
}
Py_DECREF(lookup_dict);
Py_INCREF(self);
return (PyObject *)(self);
}
typedef struct
{
listwatch_T lw;
@@ -2370,156 +2705,6 @@ ListIter(ListObject *self)
NULL, NULL);
}
static int
ListAssItem(ListObject *self, Py_ssize_t index, PyObject *obj)
{
typval_T tv;
list_T *l = self->list;
listitem_T *li;
Py_ssize_t length = ListLength(self);
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return -1;
}
if (index > length || (index == length && obj == NULL))
{
PyErr_SET_STRING(PyExc_IndexError, N_("list index out of range"));
return -1;
}
if (obj == NULL)
{
li = list_find(l, (long) index);
list_remove(l, li, li);
clear_tv(&li->li_tv);
vim_free(li);
return 0;
}
if (ConvertFromPyObject(obj, &tv) == -1)
return -1;
if (index == length)
{
if (list_append_tv(l, &tv) == FAIL)
{
clear_tv(&tv);
PyErr_SET_VIM(N_("failed to add item to list"));
return -1;
}
}
else
{
li = list_find(l, (long) index);
clear_tv(&li->li_tv);
copy_tv(&tv, &li->li_tv);
clear_tv(&tv);
}
return 0;
}
static int
ListAssSlice(ListObject *self, Py_ssize_t first, Py_ssize_t last, PyObject *obj)
{
PyInt size = ListLength(self);
PyObject *iterator;
PyObject *item;
listitem_T *li;
listitem_T *next;
typval_T v;
list_T *l = self->list;
PyInt i;
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return -1;
}
PROC_RANGE
if (first == size)
li = NULL;
else
{
li = list_find(l, (long) first);
if (li == NULL)
{
PyErr_VIM_FORMAT(N_("internal error: no vim list item %d"),
(int)first);
return -1;
}
if (last > first)
{
i = last - first;
while (i-- && li != NULL)
{
next = li->li_next;
listitem_remove(l, li);
li = next;
}
}
}
if (obj == NULL)
return 0;
if (!(iterator = PyObject_GetIter(obj)))
return -1;
while ((item = PyIter_Next(iterator)))
{
if (ConvertFromPyObject(item, &v) == -1)
{
Py_DECREF(iterator);
Py_DECREF(item);
return -1;
}
Py_DECREF(item);
if (list_insert_tv(l, &v, li) == FAIL)
{
clear_tv(&v);
PyErr_SET_VIM(N_("internal error: failed to add item to list"));
return -1;
}
clear_tv(&v);
}
Py_DECREF(iterator);
if (PyErr_Occurred())
return -1;
return 0;
}
static PyObject *
ListConcatInPlace(ListObject *self, PyObject *obj)
{
list_T *l = self->list;
PyObject *lookup_dict;
if (l->lv_lock)
{
RAISE_LOCKED_LIST;
return NULL;
}
if (!(lookup_dict = PyDict_New()))
return NULL;
if (list_py_concat(l, obj, lookup_dict) == -1)
{
Py_DECREF(lookup_dict);
return NULL;
}
Py_DECREF(lookup_dict);
Py_INCREF(self);
return (PyObject *)(self);
}
static char *ListAttrs[] = {
"locked",
NULL
@@ -2567,6 +2752,25 @@ ListSetattr(ListObject *self, char *name, PyObject *valObject)
}
}
static PySequenceMethods ListAsSeq = {
(lenfunc) ListLength, /* sq_length, len(x) */
(binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
0, /* RangeRepeat, sq_repeat, x*n */
(PyIntArgFunc) ListIndex, /* sq_item, x[i] */
0, /* was_sq_slice, x[i:j] */
(PyIntObjArgProc) ListAssIndex, /* sq_as_item, x[i]=v */
0, /* was_sq_ass_slice, x[i:j]=v */
0, /* sq_contains */
(binaryfunc) ListConcatInPlace,/* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyMappingMethods ListAsMapping = {
/* mp_length */ (lenfunc) ListLength,
/* mp_subscript */ (binaryfunc) ListItem,
/* mp_ass_subscript */ (objobjargproc) ListAssItem,
};
static struct PyMethodDef ListMethods[] = {
{"extend", (PyCFunction)ListConcatInPlace, METH_O, ""},
{"__dir__", (PyCFunction)ListDir, METH_NOARGS, ""},
@@ -2745,10 +2949,10 @@ typedef int (*checkfun)(void *);
typedef struct
{
PyObject_HEAD
int opt_type;
void *from;
checkfun Check;
PyObject *fromObj;
int opt_type;
void *from;
checkfun Check;
PyObject *fromObj;
} OptionsObject;
static int
@@ -2867,6 +3071,69 @@ OptionsItem(OptionsObject *self, PyObject *keyObject)
}
}
static int
OptionsContains(OptionsObject *self, PyObject *keyObject)
{
char_u *key;
PyObject *todecref;
if (!(key = StringToChars(keyObject, &todecref)))
return -1;
if (*key == NUL)
{
Py_XDECREF(todecref);
return 0;
}
if (get_option_value_strict(key, NULL, NULL, self->opt_type, NULL))
{
Py_XDECREF(todecref);
return 1;
}
else
{
Py_XDECREF(todecref);
return 0;
}
}
typedef struct
{
void *lastoption;
int opt_type;
} optiterinfo_T;
static PyObject *
OptionsIterNext(optiterinfo_T **oii)
{
char_u *name;
if ((name = option_iter_next(&((*oii)->lastoption), (*oii)->opt_type)))
return PyString_FromString((char *)name);
return NULL;
}
static PyObject *
OptionsIter(OptionsObject *self)
{
optiterinfo_T *oii;
if (!(oii = PyMem_New(optiterinfo_T, 1)))
{
PyErr_NoMemory();
return NULL;
}
oii->opt_type = self->opt_type;
oii->lastoption = NULL;
return IterNew(oii,
(destructorfun) PyMem_Free, (nextfun) OptionsIterNext,
NULL, NULL);
}
static int
set_option_value_err(char_u *key, int numval, char_u *stringval, int opt_flags)
{
@@ -3027,6 +3294,19 @@ OptionsAssItem(OptionsObject *self, PyObject *keyObject, PyObject *valObject)
return ret;
}
static PySequenceMethods OptionsAsSeq = {
0, /* sq_length */
0, /* sq_concat */
0, /* sq_repeat */
0, /* sq_item */
0, /* sq_slice */
0, /* sq_ass_item */
0, /* sq_ass_slice */
(objobjproc) OptionsContains, /* sq_contains */
0, /* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyMappingMethods OptionsAsMapping = {
(lenfunc) NULL,
(binaryfunc) OptionsItem,
@@ -5917,8 +6197,10 @@ init_structs(void)
vim_memset(&OptionsType, 0, sizeof(OptionsType));
OptionsType.tp_name = "vim.options";
OptionsType.tp_basicsize = sizeof(OptionsObject);
OptionsType.tp_as_sequence = &OptionsAsSeq;
OptionsType.tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC;
OptionsType.tp_doc = "object for manipulating options";
OptionsType.tp_iter = (getiterfunc)OptionsIter;
OptionsType.tp_as_mapping = &OptionsAsMapping;
OptionsType.tp_dealloc = (destructor)OptionsDestructor;
OptionsType.tp_traverse = (traverseproc)OptionsTraverse;

View File

@@ -196,6 +196,7 @@ struct PyMethodDef { Py_ssize_t a; };
# define PyTuple_Size dll_PyTuple_Size
# define PyTuple_GetItem dll_PyTuple_GetItem
# define PyTuple_Type (*dll_PyTuple_Type)
# define PySlice_GetIndicesEx dll_PySlice_GetIndicesEx
# define PyImport_ImportModule dll_PyImport_ImportModule
# define PyDict_New dll_PyDict_New
# define PyDict_GetItemString dll_PyDict_GetItemString
@@ -241,6 +242,7 @@ struct PyMethodDef { Py_ssize_t a; };
# define PySys_GetObject dll_PySys_GetObject
# define PySys_SetArgv dll_PySys_SetArgv
# define PyType_Type (*dll_PyType_Type)
# define PySlice_Type (*dll_PySlice_Type)
# define PyType_Ready (*dll_PyType_Ready)
# define PyType_GenericAlloc dll_PyType_GenericAlloc
# define Py_BuildValue dll_Py_BuildValue
@@ -341,6 +343,9 @@ static PyObject*(*dll_PySequence_Fast)(PyObject *, const char *);
static PyInt(*dll_PyTuple_Size)(PyObject *);
static PyObject*(*dll_PyTuple_GetItem)(PyObject *, PyInt);
static PyTypeObject* dll_PyTuple_Type;
static int (*dll_PySlice_GetIndicesEx)(PyObject *r, PyInt length,
PyInt *start, PyInt *stop, PyInt *step,
PyInt *slicelen);
static PyObject*(*dll_PyImport_ImportModule)(const char *);
static PyObject*(*dll_PyDict_New)(void);
static PyObject*(*dll_PyDict_GetItemString)(PyObject *, const char *);
@@ -382,6 +387,7 @@ static int(*dll_PySys_SetObject)(char *, PyObject *);
static PyObject *(*dll_PySys_GetObject)(char *);
static int(*dll_PySys_SetArgv)(int, char **);
static PyTypeObject* dll_PyType_Type;
static PyTypeObject* dll_PySlice_Type;
static int (*dll_PyType_Ready)(PyTypeObject *type);
static PyObject* (*dll_PyType_GenericAlloc)(PyTypeObject *type, PyInt nitems);
static PyObject*(*dll_Py_BuildValue)(char *, ...);
@@ -521,6 +527,7 @@ static struct
{"PyTuple_GetItem", (PYTHON_PROC*)&dll_PyTuple_GetItem},
{"PyTuple_Size", (PYTHON_PROC*)&dll_PyTuple_Size},
{"PyTuple_Type", (PYTHON_PROC*)&dll_PyTuple_Type},
{"PySlice_GetIndicesEx", (PYTHON_PROC*)&dll_PySlice_GetIndicesEx},
{"PyImport_ImportModule", (PYTHON_PROC*)&dll_PyImport_ImportModule},
{"PyDict_GetItemString", (PYTHON_PROC*)&dll_PyDict_GetItemString},
{"PyDict_Next", (PYTHON_PROC*)&dll_PyDict_Next},
@@ -562,6 +569,7 @@ static struct
{"PySys_GetObject", (PYTHON_PROC*)&dll_PySys_GetObject},
{"PySys_SetArgv", (PYTHON_PROC*)&dll_PySys_SetArgv},
{"PyType_Type", (PYTHON_PROC*)&dll_PyType_Type},
{"PySlice_Type", (PYTHON_PROC*)&dll_PySlice_Type},
{"PyType_Ready", (PYTHON_PROC*)&dll_PyType_Ready},
{"PyType_GenericAlloc", (PYTHON_PROC*)&dll_PyType_GenericAlloc},
{"Py_FindMethod", (PYTHON_PROC*)&dll_Py_FindMethod},
@@ -1472,21 +1480,6 @@ DictionaryGetattr(PyObject *self, char *name)
return Py_FindMethod(DictionaryMethods, self, name);
}
static PySequenceMethods ListAsSeq = {
(PyInquiry) ListLength,
(binaryfunc) 0,
(PyIntArgFunc) 0,
(PyIntArgFunc) ListItem,
(PyIntIntArgFunc) ListSlice,
(PyIntObjArgProc) ListAssItem,
(PyIntIntObjArgProc) ListAssSlice,
(objobjproc) 0,
#if PY_MAJOR_VERSION >= 2
(binaryfunc) ListConcatInPlace,
0,
#endif
};
static PyObject *
ListGetattr(PyObject *self, char *name)
{

View File

@@ -97,6 +97,9 @@
#define Py_ssize_t_fmt "n"
#define Py_bytes_fmt "y"
#define PyIntArgFunc ssizeargfunc
#define PyIntObjArgProc ssizeobjargproc
#if defined(DYNAMIC_PYTHON3) || defined(PROTO)
# ifndef WIN3264
@@ -292,7 +295,8 @@ static PyObject* (*py3_PyTuple_GetItem)(PyObject *, Py_ssize_t);
static int (*py3_PyMapping_Check)(PyObject *);
static PyObject* (*py3_PyMapping_Keys)(PyObject *);
static int (*py3_PySlice_GetIndicesEx)(PyObject *r, Py_ssize_t length,
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength);
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
Py_ssize_t *slicelen);
static PyObject* (*py3_PyErr_NoMemory)(void);
static void (*py3_Py_Finalize)(void);
static void (*py3_PyErr_SetString)(PyObject *, const char *);
@@ -1478,76 +1482,6 @@ DictionarySetattro(PyObject *self, PyObject *nameobj, PyObject *val)
/* List object - Definitions
*/
static PySequenceMethods ListAsSeq = {
(lenfunc) ListLength, /* sq_length, len(x) */
(binaryfunc) 0, /* RangeConcat, sq_concat, x+y */
(ssizeargfunc) 0, /* RangeRepeat, sq_repeat, x*n */
(ssizeargfunc) ListItem, /* sq_item, x[i] */
(void *) 0, /* was_sq_slice, x[i:j] */
(ssizeobjargproc) ListAssItem, /* sq_as_item, x[i]=v */
(void *) 0, /* was_sq_ass_slice, x[i:j]=v */
0, /* sq_contains */
(binaryfunc) ListConcatInPlace,/* sq_inplace_concat */
0, /* sq_inplace_repeat */
};
static PyObject *ListSubscript(PyObject *, PyObject *);
static Py_ssize_t ListAsSubscript(PyObject *, PyObject *, PyObject *);
static PyMappingMethods ListAsMapping = {
/* mp_length */ (lenfunc) ListLength,
/* mp_subscript */ (binaryfunc) ListSubscript,
/* mp_ass_subscript */ (objobjargproc) ListAsSubscript,
};
static PyObject *
ListSubscript(PyObject *self, PyObject* idx)
{
if (PyLong_Check(idx))
{
long _idx = PyLong_AsLong(idx);
return ListItem((ListObject *)(self), _idx);
}
else if (PySlice_Check(idx))
{
Py_ssize_t start, stop, step, slicelen;
if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)),
&start, &stop, &step, &slicelen) < 0)
return NULL;
return ListSlice((ListObject *)(self), start, stop);
}
else
{
RAISE_INVALID_INDEX_TYPE(idx);
return NULL;
}
}
static Py_ssize_t
ListAsSubscript(PyObject *self, PyObject *idx, PyObject *obj)
{
if (PyLong_Check(idx))
{
long _idx = PyLong_AsLong(idx);
return ListAssItem((ListObject *)(self), _idx, obj);
}
else if (PySlice_Check(idx))
{
Py_ssize_t start, stop, step, slicelen;
if (PySlice_GetIndicesEx(idx, ListLength((ListObject *)(self)),
&start, &stop, &step, &slicelen) < 0)
return -1;
return ListAssSlice((ListObject *)(self), start, stop, obj);
}
else
{
RAISE_INVALID_INDEX_TYPE(idx);
return -1;
}
}
static PyObject *
ListGetattro(PyObject *self, PyObject *nameobj)
{

View File

@@ -8861,7 +8861,7 @@ get_option_value(name, numval, stringval, opt_flags)
}
#endif
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
/*
* Returns the option attributes and its value. Unlike the above function it
* will return either global value or local value of the option depending on
@@ -8874,7 +8874,8 @@ get_option_value(name, numval, stringval, opt_flags)
* opt_type). Uses
*
* Returned flags:
* 0 hidden or unknown option
* 0 hidden or unknown option, also option that does not have requested
* type (see SREQ_* in vim.h)
* see SOPT_* in vim.h for other flags
*
* Possible opt_type values: see SREQ_* in vim.h
@@ -8997,6 +8998,68 @@ get_option_value_strict(name, numval, stringval, opt_type, from)
return r;
}
/*
* Iterate over options. First argument is a pointer to a pointer to a structure
* inside options[] array, second is option type like in the above function.
*
* If first argument points to NULL it is assumed that iteration just started
* and caller needs the very first value.
* If first argument points to the end marker function returns NULL and sets
* first argument to NULL.
*
* Returns full option name for current option on each call.
*/
char_u *
option_iter_next(option, opt_type)
void **option;
int opt_type;
{
struct vimoption *ret = NULL;
do
{
if (*option == NULL)
*option = (void *) options;
else if (((struct vimoption *) (*option))->fullname == NULL)
{
*option = NULL;
return NULL;
}
else
*option = (void *) (((struct vimoption *) (*option)) + 1);
ret = ((struct vimoption *) (*option));
/* Hidden option */
if (ret->var == NULL)
{
ret = NULL;
continue;
}
switch (opt_type)
{
case SREQ_GLOBAL:
if (!(ret->indir == PV_NONE || ret->indir & PV_BOTH))
ret = NULL;
break;
case SREQ_BUF:
if (!(ret->indir & PV_BUF))
ret = NULL;
break;
case SREQ_WIN:
if (!(ret->indir & PV_WIN))
ret = NULL;
break;
default:
EMSG2(_(e_intern2), "option_iter_next()");
return NULL;
}
}
while (ret == NULL);
return (char_u *)ret->fullname;
}
#endif
/*

View File

@@ -60,6 +60,7 @@ int list_append_dict __ARGS((list_T *list, dict_T *dict));
int list_append_string __ARGS((list_T *l, char_u *str, int len));
int list_insert_tv __ARGS((list_T *l, typval_T *tv, listitem_T *item));
void list_remove __ARGS((list_T *l, listitem_T *item, listitem_T *item2));
void list_insert __ARGS((list_T *l, listitem_T *ni, listitem_T *item));
int garbage_collect __ARGS((void));
void set_ref_in_ht __ARGS((hashtab_T *ht, int copyID));
void set_ref_in_list __ARGS((list_T *l, int copyID));

View File

@@ -23,6 +23,7 @@ char_u *check_colorcolumn __ARGS((win_T *wp));
char_u *check_stl_option __ARGS((char_u *s));
int get_option_value __ARGS((char_u *name, long *numval, char_u **stringval, int opt_flags));
int get_option_value_strict __ARGS((char_u *name, long *numval, char_u **stringval, int opt_type, void *from));
char_u *option_iter_next __ARGS((void **option, int opt_type));
char_u *set_option_value __ARGS((char_u *name, long number, char_u *string, int opt_flags));
char_u *get_term_code __ARGS((char_u *tname));
char_u *get_highlight_default __ARGS((void));

View File

@@ -201,7 +201,7 @@ search_regcomp(pat, pat_save, pat_use, options, regmatch)
* Save the currently used pattern in the appropriate place,
* unless the pattern should not be remembered.
*/
if (!(options & SEARCH_KEEP))
if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns)
{
/* search or global command */
if (pat_save == RE_SEARCH || pat_save == RE_BOTH)

View File

@@ -47,6 +47,15 @@ j:call search('^$', 'c')
/two
:call search('.', 'c')
:call append(line('$'), getline('.')[col('.') - 1:])
:"
/^substitute
:s/foo/bar/
:$put =@/
/^substitute
:keeppatterns s/asdf/xyz/
:$put =@/
/^substitute
Y:$put =@0
:/^search()/,$w >>test.out
:qa!
ENDTEST
@@ -81,6 +90,7 @@ Piece of Java
foobar
substitute foo asdf
one two
search()

View File

@@ -20,3 +20,6 @@ search()
1
1
two
foo
^substitute
substitute bar xyz

View File

@@ -135,6 +135,18 @@ EOF
:py l=vim.bindeval('l')
:py del l[-6:2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py l=vim.bindeval('l')
:py del l[::2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py l=vim.bindeval('l')
:py del l[3:0:-2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py l=vim.bindeval('l')
:py del l[2:4:-2]
:$put =string(l)
:"
:" Slice assignment to a list
:let l = [0, 1, 2, 3]
@@ -169,6 +181,26 @@ EOF
:py l=vim.bindeval('l')
:py l[0:0]=['h']
:$put =string(l)
:let l = range(8)
:py l=vim.bindeval('l')
:py l[2:6:2] = [10, 20]
:$put =string(l)
:let l = range(8)
:py l=vim.bindeval('l')
:py l[6:2:-2] = [10, 20]
:$put =string(l)
:let l = range(8)
:py l=vim.bindeval('l')
:py l[6:2] = ()
:$put =string(l)
:let l = range(8)
:py l=vim.bindeval('l')
:py l[6:2:1] = ()
:$put =string(l)
:let l = range(8)
:py l=vim.bindeval('l')
:py l[2:2:1] = ()
:$put =string(l)
:"
:" Locked variables
:let l = [0, 1, 2, 3]
@@ -390,6 +422,13 @@ EOF
:$put =string(pyeval('l'))
:py l = ll[-10:10]
:$put =string(pyeval('l'))
:py l = ll[4:2:-1]
:$put =string(pyeval('l'))
:py l = ll[::2]
:$put =string(pyeval('l'))
:py l = ll[4:2:1]
:$put =string(pyeval('l'))
:py del l
:"
:" Vars
:let g:foo = 'bac'
@@ -467,6 +506,11 @@ EOF
:py bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
:py bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
:py bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
:$put ='wopts iters equal: '.pyeval('list(wopts1) == list(wopts2)')
:$put ='bopts iters equal: '.pyeval('list(bopts1) == list(bopts2)')
:py gset=set(iter(gopts1))
:py wset=set(iter(wopts1))
:py bset=set(iter(bopts1))
:set path=.,..,,
:let lst=[]
:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
@@ -497,6 +541,8 @@ EOF
: py oval3=bool(oval3)
: endif
: put ='>>> '.oname
: $put =' g/w/b:'.pyeval('oname in gset').'/'.pyeval('oname in wset').'/'.pyeval('oname in bset')
: $put =' g/w/b (in):'.pyeval('oname in gopts1').'/'.pyeval('oname in wopts1').'/'.pyeval('oname in bopts1')
: for v in ['gopts1', 'wopts1', 'bopts1']
: try
: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
@@ -907,6 +953,7 @@ dl.locked = True
l = vim.List()
ll = vim.List('abcE')
ll.locked = True
nel = vim.List('abcO')
f = vim.Function('string')
fd = vim.Function('F')
fdel = vim.Function('D')
@@ -994,6 +1041,20 @@ class FailingIterNext(object):
def next(self):
raise NotImplementedError('next')
class FailingIterNextN(object):
def __init__(self, n):
self.n = n
def __iter__(self):
return self
def next(self):
if self.n:
self.n -= 1
return 1
else:
raise NotImplementedError('next N')
class FailingMappingKey(object):
def __getitem__(self, item):
raise NotImplementedError('getitem:mappingkey')
@@ -1068,6 +1129,13 @@ ee('import failing_import')
ee('import failing')
vim.options['rtp'] = old_rtp
del old_rtp
cb.append("> Options")
cb.append(">> OptionsItem")
ee('vim.options["abcQ"]')
ee('vim.options[""]')
stringtochars_test('vim.options[%s]')
cb.append(">> OptionsContains")
stringtochars_test('%s in vim.options')
cb.append("> Dictionary")
cb.append(">> DictionaryConstructor")
ee('vim.Dictionary("abcI")')
@@ -1098,6 +1166,7 @@ cb.append(">>> kwargs")
cb.append(">>> iter")
ee('d.update(FailingMapping())')
ee('d.update([FailingIterNext()])')
ee('d.update([FailingIterNextN(1)])')
iter_test('d.update(%s)')
convertfrompyobject_test('d.update(%s)')
stringtochars_test('d.update(((%s, 0),))')
@@ -1120,6 +1189,14 @@ ee('l[1000] = 3')
cb.append(">> ListAssSlice")
ee('ll[1:100] = "abcJ"')
iter_test('l[:] = %s')
ee('nel[1:10:2] = "abcK"')
cb.append(repr(tuple(nel)))
ee('nel[1:10:2] = "a"')
cb.append(repr(tuple(nel)))
ee('nel[1:1:-1] = "a"')
cb.append(repr(tuple(nel)))
ee('nel[:] = FailingIterNextN(2)')
cb.append(repr(tuple(nel)))
convertfrompyobject_test('l[:] = [%s]')
cb.append(">> ListConcatInPlace")
iter_test('l.extend(%s)')
@@ -1201,6 +1278,7 @@ del ned
del dl
del l
del ll
del nel
del f
del fd
del fdel
@@ -1214,6 +1292,7 @@ del number_test
del FailingTrue
del FailingIter
del FailingIterNext
del FailingIterNextN
del FailingMapping
del FailingMappingKey
del FailingList

View File

@@ -41,6 +41,9 @@ None
[2, 3]
[2, 3]
[2, 3]
[1, 3]
[0, 2]
[0, 1, 2, 3]
['a', 0, 1, 2, 3]
[0, 'b', 2, 3]
[0, 1, 'c']
@@ -49,6 +52,11 @@ None
['f', 2, 3]
[0, 1, 'g', 2, 3]
['h']
[0, 1, 10, 3, 20, 5, 6, 7]
[0, 1, 2, 3, 20, 5, 10, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3]
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
@@ -96,12 +104,19 @@ vim: Vim(let):E859:
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[4, 3]
[0, 2, 4]
[]
Abc
bac
def
bar
jkl
wopts iters equal: 1
bopts iters equal: 1
>>> paste
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: False
p/wopts1! KeyError
inv: 2! KeyError
@@ -122,6 +137,8 @@ jkl
W: 1:1 2:1 3:1 4:1
B: 1:1 2:1 3:1 4:1
>>> previewheight
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: 12
inv: 'a'! TypeError
p/wopts1! KeyError
@@ -143,6 +160,8 @@ jkl
W: 1:5 2:5 3:5 4:5
B: 1:5 2:5 3:5 4:5
>>> operatorfunc
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: ''
inv: 2! TypeError
p/wopts1! KeyError
@@ -164,6 +183,8 @@ jkl
W: 1:'A' 2:'A' 3:'A' 4:'A'
B: 1:'A' 2:'A' 3:'A' 4:'A'
>>> number
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: 0! KeyError
gopts1! KeyError
@@ -182,6 +203,8 @@ jkl
W: 1:1 2:1 3:0 4:0
B: 1:1 2:1 3:0 4:0
>>> numberwidth
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: -100! KeyError
gopts1! KeyError
@@ -201,6 +224,8 @@ jkl
W: 1:3 2:5 3:2 4:8
B: 1:3 2:5 3:2 4:8
>>> colorcolumn
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: 'abc4'! KeyError
gopts1! KeyError
@@ -220,6 +245,8 @@ jkl
W: 1:'+2' 2:'+3' 3:'+1' 4:''
B: 1:'+2' 2:'+3' 3:'+1' 4:''
>>> statusline
g/w/b:1/1/0
g/w/b (in):1/1/0
p/gopts1: ''
inv: 0! TypeError
p/wopts1: None
@@ -237,6 +264,8 @@ jkl
W: 1:'2' 2:'1' 3:'1' 4:'1'
B: 1:'2' 2:'1' 3:'1' 4:'1'
>>> autoindent
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 2! KeyError
gopts1! KeyError
@@ -255,6 +284,8 @@ jkl
W: 1:0 2:1 3:0 4:1
B: 1:0 2:1 3:0 4:1
>>> shiftwidth
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 3! KeyError
gopts1! KeyError
@@ -273,6 +304,8 @@ jkl
W: 1:0 2:2 3:8 4:1
B: 1:0 2:2 3:8 4:1
>>> omnifunc
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 1! KeyError
gopts1! KeyError
@@ -292,6 +325,8 @@ jkl
W: 1:'A' 2:'B' 3:'' 4:'C'
B: 1:'A' 2:'B' 3:'' 4:'C'
>>> preserveindent
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 2! KeyError
gopts1! KeyError
@@ -310,6 +345,8 @@ jkl
W: 1:0 2:1 3:0 4:1
B: 1:0 2:1 3:0 4:1
>>> path
g/w/b:1/0/1
g/w/b (in):1/0/1
p/gopts1: '.,..,,'
inv: 0! TypeError
p/wopts1! KeyError
@@ -498,6 +535,21 @@ vim.foreach_rtp(int, 2):TypeError:('foreach_rtp() takes exactly one argument (2
import xxx_no_such_module_xxx:ImportError:('No module named xxx_no_such_module_xxx',)
import failing_import:ImportError:('No module named failing_import',)
import failing:NotImplementedError:()
> Options
>> OptionsItem
vim.options["abcQ"]:KeyError:('abcQ',)
vim.options[""]:ValueError:('empty keys are not allowed',)
>>> Testing StringToChars using vim.options[%s]
vim.options[1]:TypeError:('expected str() or unicode() instance, but got int',)
vim.options[u"\0"]:TypeError:('expected string without null bytes',)
vim.options["\0"]:TypeError:('expected string without null bytes',)
<<< Finished
>> OptionsContains
>>> Testing StringToChars using %s in vim.options
1 in vim.options:TypeError:('expected str() or unicode() instance, but got int',)
u"\0" in vim.options:TypeError:('expected string without null bytes',)
"\0" in vim.options:TypeError:('expected string without null bytes',)
<<< Finished
> Dictionary
>> DictionaryConstructor
vim.Dictionary("abcI"):ValueError:('expected sequence element of size 2, but got sequence of size 1',)
@@ -599,6 +651,7 @@ d["a"] = FailingNumber():TypeError:('long() argument must be a string or a numbe
>>> iter
d.update(FailingMapping()):NotImplementedError:('keys',)
d.update([FailingIterNext()]):NotImplementedError:('next',)
d.update([FailingIterNextN(1)]):NotImplementedError:('next N',)
>>> Testing *Iter* using d.update(%s)
d.update(FailingIter()):NotImplementedError:('iter',)
d.update(FailingIterNext()):NotImplementedError:('next',)
@@ -829,6 +882,14 @@ ll[1:100] = "abcJ":error:('list is locked',)
l[:] = FailingIter():NotImplementedError:('iter',)
l[:] = FailingIterNext():NotImplementedError:('next',)
<<< Finished
nel[1:10:2] = "abcK":ValueError:('attempt to assign sequence of size greater then 2 to extended slice',)
('a', 'b', 'c', 'O')
nel[1:10:2] = "a":ValueError:('attempt to assign sequence of size 1 to extended slice of size 2',)
('a', 'b', 'c', 'O')
nel[1:1:-1] = "a":ValueError:('attempt to assign sequence of size greater then 0 to extended slice',)
('a', 'b', 'c', 'O')
nel[:] = FailingIterNextN(2):NotImplementedError:('next N',)
('a', 'b', 'c', 'O')
>>> Testing StringToChars using l[:] = [{%s : 1}]
l[:] = [{1 : 1}]:TypeError:('expected str() or unicode() instance, but got int',)
l[:] = [{u"\0" : 1}]:TypeError:('expected string without null bytes',)

View File

@@ -128,6 +128,18 @@ EOF
:py3 l=vim.bindeval('l')
:py3 del l[-6:2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py3 l=vim.bindeval('l')
:py3 del l[::2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py3 l=vim.bindeval('l')
:py3 del l[3:0:-2]
:$put =string(l)
:let l = [0, 1, 2, 3]
:py3 l=vim.bindeval('l')
:py3 del l[2:4:-2]
:$put =string(l)
:"
:" Slice assignment to a list
:let l = [0, 1, 2, 3]
@@ -162,6 +174,26 @@ EOF
:py3 l=vim.bindeval('l')
:py3 l[0:0]=['h']
:$put =string(l)
:let l = range(8)
:py3 l=vim.bindeval('l')
:py3 l[2:6:2] = [10, 20]
:$put =string(l)
:let l = range(8)
:py3 l=vim.bindeval('l')
:py3 l[6:2:-2] = [10, 20]
:$put =string(l)
:let l = range(8)
:py3 l=vim.bindeval('l')
:py3 l[6:2] = ()
:$put =string(l)
:let l = range(8)
:py3 l=vim.bindeval('l')
:py3 l[6:2:1] = ()
:$put =string(l)
:let l = range(8)
:py3 l=vim.bindeval('l')
:py3 l[2:2:1] = ()
:$put =string(l)
:"
:" Locked variables
:let l = [0, 1, 2, 3]
@@ -363,6 +395,38 @@ EOF
:py3 del trace_main
:$put =string(l)
:"
:" Slice
:py3 ll = vim.bindeval('[0, 1, 2, 3, 4, 5]')
:py3 l = ll[:4]
:$put =string(py3eval('l'))
:py3 l = ll[2:]
:$put =string(py3eval('l'))
:py3 l = ll[:-4]
:$put =string(py3eval('l'))
:py3 l = ll[-2:]
:$put =string(py3eval('l'))
:py3 l = ll[2:4]
:$put =string(py3eval('l'))
:py3 l = ll[4:2]
:$put =string(py3eval('l'))
:py3 l = ll[-4:-2]
:$put =string(py3eval('l'))
:py3 l = ll[-2:-4]
:$put =string(py3eval('l'))
:py3 l = ll[:]
:$put =string(py3eval('l'))
:py3 l = ll[0:6]
:$put =string(py3eval('l'))
:py3 l = ll[-10:10]
:$put =string(py3eval('l'))
:py3 l = ll[4:2:-1]
:$put =string(py3eval('l'))
:py3 l = ll[::2]
:$put =string(py3eval('l'))
:py3 l = ll[4:2:1]
:$put =string(py3eval('l'))
:py3 del l
:"
:" Vars
:let g:foo = 'bac'
:let w:abc3 = 'def'
@@ -439,6 +503,11 @@ EOF
:py3 bopts1=vim.buffers[vim.bindeval("g:bufs")[2]].options
:py3 bopts2=vim.buffers[vim.bindeval("g:bufs")[1]].options
:py3 bopts3=vim.buffers[vim.bindeval("g:bufs")[0]].options
:$put ='wopts iters equal: '.py3eval('list(wopts1) == list(wopts2)')
:$put ='bopts iters equal: '.py3eval('list(bopts1) == list(bopts2)')
:py3 gset=set(iter(gopts1))
:py3 wset=set(iter(wopts1))
:py3 bset=set(iter(bopts1))
:set path=.,..,,
:let lst=[]
:let lst+=[['paste', 1, 0, 1, 2, 1, 1, 0 ]]
@@ -469,6 +538,8 @@ EOF
: py3 oval3=bool(oval3)
: endif
: put ='>>> '.oname
: $put =' g/w/b:'.py3eval('oname in gset').'/'.py3eval('oname in wset').'/'.py3eval('oname in bset')
: $put =' g/w/b (in):'.py3eval('oname in gopts1').'/'.py3eval('oname in wopts1').'/'.py3eval('oname in bopts1')
: for v in ['gopts1', 'wopts1', 'bopts1']
: try
: put =' p/'.v.': '.Ev('repr('.v.'['''.oname.'''])')
@@ -859,6 +930,7 @@ dl.locked = True
l = vim.List()
ll = vim.List('abcE')
ll.locked = True
nel = vim.List('abcO')
f = vim.Function('string')
fd = vim.Function('F')
fdel = vim.Function('D')
@@ -946,6 +1018,20 @@ class FailingIterNext(object):
def __next__(self):
raise NotImplementedError('next')
class FailingIterNextN(object):
def __init__(self, n):
self.n = n
def __iter__(self):
return self
def __next__(self):
if self.n:
self.n -= 1
return 1
else:
raise NotImplementedError('next N')
class FailingMappingKey(object):
def __getitem__(self, item):
raise NotImplementedError('getitem:mappingkey')
@@ -1020,6 +1106,13 @@ ee('import failing_import')
ee('import failing')
vim.options['rtp'] = old_rtp
del old_rtp
cb.append("> Options")
cb.append(">> OptionsItem")
ee('vim.options["abcQ"]')
ee('vim.options[""]')
stringtochars_test('vim.options[%s]')
cb.append(">> OptionsContains")
stringtochars_test('%s in vim.options')
cb.append("> Dictionary")
cb.append(">> DictionaryConstructor")
ee('vim.Dictionary("abcI")')
@@ -1050,6 +1143,7 @@ cb.append(">>> kwargs")
cb.append(">>> iter")
ee('d.update(FailingMapping())')
ee('d.update([FailingIterNext()])')
ee('d.update([FailingIterNextN(1)])')
iter_test('d.update(%s)')
convertfrompyobject_test('d.update(%s)')
stringtochars_test('d.update(((%s, 0),))')
@@ -1072,6 +1166,14 @@ ee('l[1000] = 3')
cb.append(">> ListAssSlice")
ee('ll[1:100] = "abcJ"')
iter_test('l[:] = %s')
ee('nel[1:10:2] = "abcK"')
cb.append(repr(tuple(nel)))
ee('nel[1:10:2] = "a"')
cb.append(repr(tuple(nel)))
ee('nel[1:1:-1] = "a"')
cb.append(repr(tuple(nel)))
ee('nel[:] = FailingIterNextN(2)')
cb.append(repr(tuple(nel)))
convertfrompyobject_test('l[:] = [%s]')
cb.append(">> ListConcatInPlace")
iter_test('l.extend(%s)')
@@ -1153,6 +1255,7 @@ del ned
del dl
del l
del ll
del nel
del f
del fd
del fdel
@@ -1166,6 +1269,7 @@ del number_test
del FailingTrue
del FailingIter
del FailingIterNext
del FailingIterNextN
del FailingMapping
del FailingMappingKey
del FailingList

View File

@@ -41,6 +41,9 @@ None
[2, 3]
[2, 3]
[2, 3]
[1, 3]
[0, 2]
[0, 1, 2, 3]
['a', 0, 1, 2, 3]
[0, 'b', 2, 3]
[0, 1, 'c']
@@ -49,6 +52,11 @@ None
['f', 2, 3]
[0, 1, 'g', 2, 3]
['h']
[0, 1, 10, 3, 20, 5, 6, 7]
[0, 1, 2, 3, 20, 5, 10, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3]
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd']
[function('New'), function('DictNew'), 'NewStart', 1, 2, 3, 'NewEnd', 'DictNewStart', 1, 2, 3, 'DictNewEnd', {'a': 'b'}]
@@ -85,12 +93,30 @@ undefined_name: Vim(let):Trace
vim: Vim(let):E859:
[1]
[1, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 1]
[0, 1, 2, 3]
[2, 3, 4, 5]
[0, 1]
[4, 5]
[2, 3]
[]
[2, 3]
[]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5]
[4, 3]
[0, 2, 4]
[]
Abc
bac
def
bar
jkl
wopts iters equal: 1
bopts iters equal: 1
>>> paste
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: False
p/wopts1! KeyError
inv: 2! KeyError
@@ -111,6 +137,8 @@ jkl
W: 1:1 2:1 3:1 4:1
B: 1:1 2:1 3:1 4:1
>>> previewheight
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: 12
inv: 'a'! TypeError
p/wopts1! KeyError
@@ -132,6 +160,8 @@ jkl
W: 1:5 2:5 3:5 4:5
B: 1:5 2:5 3:5 4:5
>>> operatorfunc
g/w/b:1/0/0
g/w/b (in):1/0/0
p/gopts1: b''
inv: 2! TypeError
p/wopts1! KeyError
@@ -153,6 +183,8 @@ jkl
W: 1:'A' 2:'A' 3:'A' 4:'A'
B: 1:'A' 2:'A' 3:'A' 4:'A'
>>> number
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: 0! KeyError
gopts1! KeyError
@@ -171,6 +203,8 @@ jkl
W: 1:1 2:1 3:0 4:0
B: 1:1 2:1 3:0 4:0
>>> numberwidth
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: -100! KeyError
gopts1! KeyError
@@ -190,6 +224,8 @@ jkl
W: 1:3 2:5 3:2 4:8
B: 1:3 2:5 3:2 4:8
>>> colorcolumn
g/w/b:0/1/0
g/w/b (in):0/1/0
p/gopts1! KeyError
inv: 'abc4'! KeyError
gopts1! KeyError
@@ -209,6 +245,8 @@ jkl
W: 1:'+2' 2:'+3' 3:'+1' 4:''
B: 1:'+2' 2:'+3' 3:'+1' 4:''
>>> statusline
g/w/b:1/1/0
g/w/b (in):1/1/0
p/gopts1: b''
inv: 0! TypeError
p/wopts1: None
@@ -226,6 +264,8 @@ jkl
W: 1:'2' 2:'1' 3:'1' 4:'1'
B: 1:'2' 2:'1' 3:'1' 4:'1'
>>> autoindent
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 2! KeyError
gopts1! KeyError
@@ -244,6 +284,8 @@ jkl
W: 1:0 2:1 3:0 4:1
B: 1:0 2:1 3:0 4:1
>>> shiftwidth
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 3! KeyError
gopts1! KeyError
@@ -262,6 +304,8 @@ jkl
W: 1:0 2:2 3:8 4:1
B: 1:0 2:2 3:8 4:1
>>> omnifunc
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 1! KeyError
gopts1! KeyError
@@ -281,6 +325,8 @@ jkl
W: 1:'A' 2:'B' 3:'' 4:'C'
B: 1:'A' 2:'B' 3:'' 4:'C'
>>> preserveindent
g/w/b:0/0/1
g/w/b (in):0/0/1
p/gopts1! KeyError
inv: 2! KeyError
gopts1! KeyError
@@ -299,6 +345,8 @@ jkl
W: 1:0 2:1 3:0 4:1
B: 1:0 2:1 3:0 4:1
>>> path
g/w/b:1/0/1
g/w/b (in):1/0/1
p/gopts1: b'.,..,,'
inv: 0! TypeError
p/wopts1! KeyError
@@ -487,6 +535,21 @@ vim.foreach_rtp(int, 2):(<class 'TypeError'>, TypeError('foreach_rtp() takes exa
import xxx_no_such_module_xxx:(<class 'ImportError'>, ImportError('No module named xxx_no_such_module_xxx',))
import failing_import:(<class 'ImportError'>, ImportError('No module named failing_import',))
import failing:(<class 'NotImplementedError'>, NotImplementedError())
> Options
>> OptionsItem
vim.options["abcQ"]:(<class 'KeyError'>, KeyError('abcQ',))
vim.options[""]:(<class 'ValueError'>, ValueError('empty keys are not allowed',))
>>> Testing StringToChars using vim.options[%s]
vim.options[1]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
vim.options[b"\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
vim.options["\0"]:(<class 'TypeError'>, TypeError('expected bytes with no null',))
<<< Finished
>> OptionsContains
>>> Testing StringToChars using %s in vim.options
1 in vim.options:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
b"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
"\0" in vim.options:(<class 'TypeError'>, TypeError('expected bytes with no null',))
<<< Finished
> Dictionary
>> DictionaryConstructor
vim.Dictionary("abcI"):(<class 'ValueError'>, ValueError('expected sequence element of size 2, but got sequence of size 1',))
@@ -588,6 +651,7 @@ d["a"] = FailingNumber():(<class 'NotImplementedError'>, NotImplementedError('in
>>> iter
d.update(FailingMapping()):(<class 'NotImplementedError'>, NotImplementedError('keys',))
d.update([FailingIterNext()]):(<class 'NotImplementedError'>, NotImplementedError('next',))
d.update([FailingIterNextN(1)]):(<class 'NotImplementedError'>, NotImplementedError('next N',))
>>> Testing *Iter* using d.update(%s)
d.update(FailingIter()):(<class 'NotImplementedError'>, NotImplementedError('iter',))
d.update(FailingIterNext()):(<class 'NotImplementedError'>, NotImplementedError('next',))
@@ -818,6 +882,14 @@ ll[1:100] = "abcJ":(<class 'vim.error'>, error('list is locked',))
l[:] = FailingIter():(<class 'NotImplementedError'>, NotImplementedError('iter',))
l[:] = FailingIterNext():(<class 'NotImplementedError'>, NotImplementedError('next',))
<<< Finished
nel[1:10:2] = "abcK":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 2 to extended slice',))
(b'a', b'b', b'c', b'O')
nel[1:10:2] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size 1 to extended slice of size 2',))
(b'a', b'b', b'c', b'O')
nel[1:1:-1] = "a":(<class 'ValueError'>, ValueError('attempt to assign sequence of size greater then 0 to extended slice',))
(b'a', b'b', b'c', b'O')
nel[:] = FailingIterNextN(2):(<class 'NotImplementedError'>, NotImplementedError('next N',))
(b'a', b'b', b'c', b'O')
>>> Testing StringToChars using l[:] = [{%s : 1}]
l[:] = [{1 : 1}]:(<class 'TypeError'>, TypeError('expected bytes() or str() instance, but got int',))
l[:] = [{b"\0" : 1}]:(<class 'TypeError'>, TypeError('expected bytes with no null',))

View File

@@ -738,6 +738,12 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
152,
/**/
151,
/**/
150,
/**/
149,
/**/

View File

@@ -2249,6 +2249,7 @@ typedef int VimClipboard; /* This is required for the prototypes. */
#define SOPT_BUF 0x20 /* Option has buffer-local value */
#define SOPT_UNSET 0x40 /* Option does not have local value set */
/* Option types for various functions in option.c */
#define SREQ_GLOBAL 0 /* Request global option */
#define SREQ_WIN 1 /* Request window-local option */
#define SREQ_BUF 2 /* Request buffer-local option */