changeset 4393:80eea7a9d6b9 v7.3.945

updated for version 7.3.945 Problem: Python: List of buffers is not very useful. Solution: Make vim.buffers a map. No iterator yet. (ZyX)
author Bram Moolenaar <bram@vim.org>
date Wed, 15 May 2013 13:38:47 +0200
parents 430672fe7d54
children b4941edc4984
files runtime/doc/if_pyth.txt src/if_py_both.h src/if_python.c src/if_python3.c src/testdir/test86.ok src/testdir/test87.ok src/version.c
diffstat 7 files changed, 89 insertions(+), 102 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -209,12 +209,11 @@ Constants of the "vim" module
 	to which the variables referred.
 
 vim.buffers						*python-buffers*
-	A sequence object providing access to the list of vim buffers.  The
+	A mapping object providing access to the list of vim buffers.  The
 	object supports the following operations: >
 	    :py b = vim.buffers[i]	# Indexing (read-only)
 	    :py b in vim.buffers	# Membership test
 	    :py n = len(vim.buffers)	# Number of elements
-	    :py for b in vim.buffers:	# Sequential access
 <
 vim.windows						*python-windows*
 	A sequence object providing access to the list of vim windows.  The
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -534,16 +534,15 @@ static struct PyMethodDef VimMethods[] =
  * Buffer list object - Implementation
  */
 
-static PyTypeObject BufListType;
-static PySequenceMethods BufListAsSeq;
+static PyTypeObject BufMapType;
 
 typedef struct
 {
     PyObject_HEAD
-} BufListObject;
+} BufMapObject;
 
     static PyInt
-BufListLength(PyObject *self UNUSED)
+BufMapLength(PyObject *self UNUSED)
 {
     buf_T	*b = firstbuf;
     PyInt	n = 0;
@@ -558,20 +557,41 @@ BufListLength(PyObject *self UNUSED)
 }
 
     static PyObject *
-BufListItem(PyObject *self UNUSED, PyInt n)
+BufMapItem(PyObject *self UNUSED, PyObject *keyObject)
 {
-    buf_T *b;
-
-    for (b = firstbuf; b; b = b->b_next, --n)
+    buf_T	*b;
+    int		bnr;
+
+#if PY_MAJOR_VERSION < 3
+    if (PyInt_Check(keyObject))
+	bnr = PyInt_AsLong(keyObject);
+    else
+#endif
+    if (PyLong_Check(keyObject))
+	bnr = PyLong_AsLong(keyObject);
+    else
     {
-	if (n == 0)
-	    return BufferNew(b);
+	PyErr_SetString(PyExc_ValueError, _("key must be integer"));
+	return NULL;
     }
 
-    PyErr_SetString(PyExc_IndexError, _("no such buffer"));
-    return NULL;
+    b = buflist_findnr(bnr);
+
+    if (b)
+	return BufferNew(b);
+    else
+    {
+	PyErr_SetString(PyExc_KeyError, _("no such buffer"));
+	return NULL;
+    }
 }
 
+static PyMappingMethods BufMapAsMapping = {
+    (lenfunc)       BufMapLength,
+    (binaryfunc)    BufMapItem,
+    (objobjargproc) 0,
+};
+
 typedef struct pylinkedlist_S {
     struct pylinkedlist_S	*pll_next;
     struct pylinkedlist_S	*pll_prev;
@@ -3401,11 +3421,11 @@ init_structs(void)
     WindowType.tp_setattr = WindowSetattr;
 #endif
 
-    vim_memset(&BufListType, 0, sizeof(BufListType));
-    BufListType.tp_name = "vim.bufferlist";
-    BufListType.tp_basicsize = sizeof(BufListObject);
-    BufListType.tp_as_sequence = &BufListAsSeq;
-    BufListType.tp_flags = Py_TPFLAGS_DEFAULT;
+    vim_memset(&BufMapType, 0, sizeof(BufMapType));
+    BufMapType.tp_name = "vim.bufferlist";
+    BufMapType.tp_basicsize = sizeof(BufMapObject);
+    BufMapType.tp_as_mapping = &BufMapAsMapping;
+    BufMapType.tp_flags = Py_TPFLAGS_DEFAULT;
     BufferType.tp_doc = "vim buffer list";
 
     vim_memset(&WinListType, 0, sizeof(WinListType));
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -1131,24 +1131,6 @@ RangeAssSlice(PyObject *self, PyInt lo, 
 		      &((RangeObject *)(self))->end);
 }
 
-/* Buffer list object - Definitions
- */
-
-static PySequenceMethods BufListAsSeq = {
-    (PyInquiry)		BufListLength,	    /* sq_length,    len(x)   */
-    (binaryfunc)	0,		    /* sq_concat,    x+y      */
-    (PyIntArgFunc)	0,		    /* sq_repeat,    x*n      */
-    (PyIntArgFunc)	BufListItem,	    /* sq_item,      x[i]     */
-    (PyIntIntArgFunc)	0,		    /* sq_slice,     x[i:j]   */
-    (PyIntObjArgProc)	0,		    /* sq_ass_item,  x[i]=v   */
-    (PyIntIntObjArgProc) 0,		    /* sq_ass_slice, x[i:j]=v */
-    (objobjproc)	0,
-#if PY_MAJOR_VERSION >= 2
-    (binaryfunc)	0,
-    0,
-#endif
-};
-
 /* Window object - Implementation
  */
 
@@ -1212,9 +1194,9 @@ python_window_free(win_T *win)
 }
 #endif
 
-static BufListObject TheBufferList =
+static BufMapObject TheBufferMap =
 {
-    PyObject_HEAD_INIT(&BufListType)
+    PyObject_HEAD_INIT(&BufMapType)
 };
 
 static WinListObject TheWindowList =
@@ -1240,7 +1222,7 @@ PythonMod_Init(void)
     PyType_Ready(&BufferType);
     PyType_Ready(&RangeType);
     PyType_Ready(&WindowType);
-    PyType_Ready(&BufListType);
+    PyType_Ready(&BufMapType);
     PyType_Ready(&WinListType);
     PyType_Ready(&CurrentType);
     PyType_Ready(&OptionsType);
@@ -1254,7 +1236,7 @@ PythonMod_Init(void)
     VimError = Py_BuildValue("s", "vim.error");
 
     PyDict_SetItemString(dict, "error", VimError);
-    PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferList);
+    PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferMap);
     PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent);
     PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList);
     tmp = DictionaryNew(&globvardict);
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -1272,22 +1272,6 @@ RangeAsSubscript(PyObject *self, PyObjec
     }
 }
 
-/* Buffer list object - Definitions
- */
-
-static PySequenceMethods BufListAsSeq = {
-    (lenfunc)		BufListLength,	    /* sq_length,    len(x)   */
-    (binaryfunc)	0,		    /* sq_concat,    x+y      */
-    (ssizeargfunc)	0,		    /* sq_repeat,    x*n      */
-    (ssizeargfunc)	BufListItem,	    /* sq_item,      x[i]     */
-    0,					    /* was_sq_slice,	 x[i:j]   */
-    (ssizeobjargproc)	0,		    /* sq_as_item,  x[i]=v   */
-    0,					    /* sq_ass_slice, x[i:j]=v */
-    0,					    /* sq_contains */
-    0,					    /* sq_inplace_concat */
-    0,					    /* sq_inplace_repeat */
-};
-
 /* Window object - Implementation
  */
 
@@ -1512,9 +1496,9 @@ python3_window_free(win_T *win)
 }
 #endif
 
-static BufListObject TheBufferList =
+static BufMapObject TheBufferMap =
 {
-    PyObject_HEAD_INIT(&BufListType)
+    PyObject_HEAD_INIT(&BufMapType)
 };
 
 static WinListObject TheWindowList =
@@ -1538,7 +1522,7 @@ Py3Init_vim(void)
     PyType_Ready(&BufferType);
     PyType_Ready(&RangeType);
     PyType_Ready(&WindowType);
-    PyType_Ready(&BufListType);
+    PyType_Ready(&BufMapType);
     PyType_Ready(&WinListType);
     PyType_Ready(&CurrentType);
     PyType_Ready(&DictionaryType);
@@ -1557,8 +1541,8 @@ Py3Init_vim(void)
     Py_INCREF(VimError);
 
     PyModule_AddObject(mod, "error", VimError);
-    Py_INCREF((PyObject *)(void *)&TheBufferList);
-    PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferList);
+    Py_INCREF((PyObject *)(void *)&TheBufferMap);
+    PyModule_AddObject(mod, "buffers", (PyObject *)(void *)&TheBufferMap);
     Py_INCREF((PyObject *)(void *)&TheCurrent);
     PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
     Py_INCREF((PyObject *)(void *)&TheWindowList);
--- a/src/testdir/test86.ok
+++ b/src/testdir/test86.ok
@@ -226,13 +226,13 @@ bar
   p/bopts1: False
   inv: 2! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
 >>> iminsert
   p/gopts1! KeyError
   inv: 3! KeyError
@@ -244,13 +244,13 @@ bar
   wopts3! KeyError
   p/bopts1: 2
   G: 1
-  W: 1:2 2:1 3:0 4:2
-  B: 1:2 2:1 3:0 4:2
+  W: 1:0 2:2 3:2 4:1
+  B: 1:0 2:2 3:2 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 1
-  W: 1:2 2:1 3:0 4:2
-  B: 1:2 2:1 3:0 4:2
+  W: 1:0 2:2 3:2 4:1
+  B: 1:0 2:2 3:2 4:1
 >>> omnifunc
   p/gopts1! KeyError
   inv: 1! KeyError
@@ -263,13 +263,13 @@ bar
   p/bopts1: ''
   inv: 1! ValueError
   G: ''
-  W: 1:'B' 2:'C' 3:'A' 4:''
-  B: 1:'B' 2:'C' 3:'A' 4:''
+  W: 1:'A' 2:'B' 3:'' 4:'C'
+  B: 1:'A' 2:'B' 3:'' 4:'C'
   del wopts3! KeyError
   del bopts3! ValueError
   G: ''
-  W: 1:'B' 2:'C' 3:'A' 4:''
-  B: 1:'B' 2:'C' 3:'A' 4:''
+  W: 1:'A' 2:'B' 3:'' 4:'C'
+  B: 1:'A' 2:'B' 3:'' 4:'C'
 >>> preserveindent
   p/gopts1! KeyError
   inv: 2! KeyError
@@ -282,13 +282,13 @@ bar
   p/bopts1: False
   inv: 2! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
 >>> path
   p/gopts1: '.,/usr/include,,'
   inv: 0! ValueError
@@ -300,12 +300,12 @@ bar
   p/bopts1: None
   inv: 0! ValueError
   G: '.,,'
-  W: 1:',,' 2:'.' 3:'.,,' 4:'.,,'
-  B: 1:',,' 2:'.' 3:'.,,' 4:'.,,'
+  W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+  B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
   del wopts3! KeyError
   G: '.,,'
-  W: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,'
-  B: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,'
+  W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+  B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
 First line
 First line
 def
--- a/src/testdir/test87.ok
+++ b/src/testdir/test87.ok
@@ -215,13 +215,13 @@ bar
   p/bopts1: False
   inv: 2! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
 >>> iminsert
   p/gopts1! KeyError
   inv: 3! KeyError
@@ -233,13 +233,13 @@ bar
   wopts3! KeyError
   p/bopts1: 2
   G: 1
-  W: 1:2 2:1 3:0 4:2
-  B: 1:2 2:1 3:0 4:2
+  W: 1:0 2:2 3:2 4:1
+  B: 1:0 2:2 3:2 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 1
-  W: 1:2 2:1 3:0 4:2
-  B: 1:2 2:1 3:0 4:2
+  W: 1:0 2:2 3:2 4:1
+  B: 1:0 2:2 3:2 4:1
 >>> omnifunc
   p/gopts1! KeyError
   inv: 1! KeyError
@@ -252,13 +252,13 @@ bar
   p/bopts1: b''
   inv: 1! ValueError
   G: ''
-  W: 1:'B' 2:'C' 3:'A' 4:''
-  B: 1:'B' 2:'C' 3:'A' 4:''
+  W: 1:'A' 2:'B' 3:'' 4:'C'
+  B: 1:'A' 2:'B' 3:'' 4:'C'
   del wopts3! KeyError
   del bopts3! ValueError
   G: ''
-  W: 1:'B' 2:'C' 3:'A' 4:''
-  B: 1:'B' 2:'C' 3:'A' 4:''
+  W: 1:'A' 2:'B' 3:'' 4:'C'
+  B: 1:'A' 2:'B' 3:'' 4:'C'
 >>> preserveindent
   p/gopts1! KeyError
   inv: 2! KeyError
@@ -271,13 +271,13 @@ bar
   p/bopts1: False
   inv: 2! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
   del wopts3! KeyError
   del bopts3! ValueError
   G: 0
-  W: 1:1 2:1 3:0 4:0
-  B: 1:1 2:1 3:0 4:0
+  W: 1:0 2:1 3:0 4:1
+  B: 1:0 2:1 3:0 4:1
 >>> path
   p/gopts1: b'.,/usr/include,,'
   inv: 0! ValueError
@@ -289,12 +289,12 @@ bar
   p/bopts1: None
   inv: 0! ValueError
   G: '.,,'
-  W: 1:',,' 2:'.' 3:'.,,' 4:'.,,'
-  B: 1:',,' 2:'.' 3:'.,,' 4:'.,,'
+  W: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
+  B: 1:'.,,' 2:',,' 3:'.,,' 4:'.'
   del wopts3! KeyError
   G: '.,,'
-  W: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,'
-  B: 1:',,' 2:'.,,' 3:'.,,' 4:'.,,'
+  W: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
+  B: 1:'.,,' 2:',,' 3:'.,,' 4:'.,,'
 First line
 First line
 def
--- a/src/version.c
+++ b/src/version.c
@@ -729,6 +729,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    945,
+/**/
     944,
 /**/
     943,