summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <bram@vim.org>2013-05-15 15:12:29 +0200
committerBram Moolenaar <bram@vim.org>2013-05-15 15:12:29 +0200
commitb276788237fb703f4acd01ab32a90cb37f519cdf (patch)
tree319d1641a3cb93b408b20422d0700ddd6cd5b813
parente9b60da324cf3b6923d163cbd4af5b4c263a8c29 (diff)
downloadvim-b276788237fb703f4acd01ab32a90cb37f519cdf.tar.gz
updated for version 7.3.949v7.3.949v7-3-949
Problem: Python: no easy access to tabpages. Solution: Add vim.tabpages and vim.current.tabpage. (ZyX)
-rw-r--r--runtime/doc/if_pyth.txt35
-rw-r--r--src/if_py_both.h242
-rw-r--r--src/if_python.c58
-rw-r--r--src/if_python3.c59
-rw-r--r--src/proto/if_python.pro1
-rw-r--r--src/proto/if_python3.pro1
-rw-r--r--src/proto/window.pro3
-rw-r--r--src/structs.h8
-rw-r--r--src/version.c2
-rw-r--r--src/window.c28
10 files changed, 425 insertions, 12 deletions
diff --git a/runtime/doc/if_pyth.txt b/runtime/doc/if_pyth.txt
index 22c12a0d..a358f86c 100644
--- a/runtime/doc/if_pyth.txt
+++ b/runtime/doc/if_pyth.txt
@@ -223,6 +223,20 @@ vim.windows *python-windows*
:py w in vim.windows # Membership test
:py n = len(vim.windows) # Number of elements
:py for w in vim.windows: # Sequential access
+< Note: vim.windows object always accesses current tab page,.
+ |python-tabpage|.windows objects are bound to parent |python-tabpage|
+ object and always use windows from that tab page (or throw vim.error
+ in case tab page was deleted). You can keep a reference to both
+ without keeping a reference to vim module object or |python-tabpage|,
+ they will not loose their properties in this case.
+
+vim.tabpages *python-tabpages*
+ A sequence object providing access to the list of vim tab pages. The
+ object supports the following operations: >
+ :py t = vim.tabpages[i] # Indexing (read-only)
+ :py t in vim.tabpages # Membership test
+ :py n = len(vim.tabpages) # Number of elements
+ :py for t in vim.tabpages: # Sequential access
<
vim.current *python-current*
An object providing access (via specific attributes) to various
@@ -230,6 +244,7 @@ vim.current *python-current*
vim.current.line The current line (RW) String
vim.current.buffer The current buffer (RO) Buffer
vim.current.window The current window (RO) Window
+ vim.current.tabpage The current tab page (RO) TabPage
vim.current.range The current line range (RO) Range
The last case deserves a little explanation. When the :python or
@@ -375,6 +390,8 @@ Example (assume r is the current range):
Window objects represent vim windows. You can obtain them in a number of ways:
- via vim.current.window (|python-current|)
- from indexing vim.windows (|python-windows|)
+ - from indexing "windows" attribute of a tab page (|python-tabpage|)
+ - from the "window" attribute of a tab page (|python-tabpage|)
You can manipulate window objects only through their attributes. They have no
methods, and no sequence or other interface.
@@ -407,6 +424,24 @@ The height attribute is writable only if the screen is split horizontally.
The width attribute is writable only if the screen is split vertically.
==============================================================================
+6. Tab page objects *python-tabpage*
+
+Tab page objects represent vim tab pages. You can obtain them in a number of
+ways:
+ - via vim.current.tabpage (|python-current|)
+ - from indexing vim.tabpages (|python-tabpages|)
+
+You can use this object to access tab page windows. They have no methods and
+no sequence or other interfaces.
+
+Tab page attributes are:
+ number The tab page number like the one returned by
+ |tabpagenr()|.
+ windows Like |python-windows|, but for current tab page.
+ vars The tab page |t:| variables.
+ window Current tabpage window.
+
+==============================================================================
6. pyeval() and py3eval() Vim functions *python-pyeval*
To facilitate bi-directional interface, you can use |pyeval()| and |py3eval()|
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 6f916695..b80a3e24 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -27,6 +27,7 @@ typedef int Py_ssize_t; /* Python 2.4 and earlier don't have this type. */
#define INVALID_BUFFER_VALUE ((buf_T *)(-1))
#define INVALID_WINDOW_VALUE ((win_T *)(-1))
+#define INVALID_TABPAGE_VALUE ((tabpage_T *)(-1))
static int ConvertFromPyObject(PyObject *, typval_T *);
static int _ConvertFromPyObject(PyObject *, typval_T *, PyObject *);
@@ -1579,6 +1580,155 @@ static PyMappingMethods OptionsAsMapping = {
(objobjargproc) OptionsAssItem,
};
+/* Tabpage object
+ */
+
+typedef struct
+{
+ PyObject_HEAD
+ tabpage_T *tab;
+} TabPageObject;
+
+static PyObject *WinListNew(TabPageObject *tabObject);
+
+static PyTypeObject TabPageType;
+
+ static int
+CheckTabPage(TabPageObject *this)
+{
+ if (this->tab == INVALID_TABPAGE_VALUE)
+ {
+ PyErr_SetVim(_("attempt to refer to deleted tab page"));
+ return -1;
+ }
+
+ return 0;
+}
+
+ static PyObject *
+TabPageNew(tabpage_T *tab)
+{
+ TabPageObject *self;
+
+ if (TAB_PYTHON_REF(tab))
+ {
+ self = TAB_PYTHON_REF(tab);
+ Py_INCREF(self);
+ }
+ else
+ {
+ self = PyObject_NEW(TabPageObject, &TabPageType);
+ if (self == NULL)
+ return NULL;
+ self->tab = tab;
+ TAB_PYTHON_REF(tab) = self;
+ }
+
+ return (PyObject *)(self);
+}
+
+ static void
+TabPageDestructor(PyObject *self)
+{
+ TabPageObject *this = (TabPageObject *)(self);
+
+ if (this->tab && this->tab != INVALID_TABPAGE_VALUE)
+ TAB_PYTHON_REF(this->tab) = NULL;
+
+ DESTRUCTOR_FINISH(self);
+}
+
+ static PyObject *
+TabPageAttr(TabPageObject *this, char *name)
+{
+ if (strcmp(name, "windows") == 0)
+ return WinListNew(this);
+ else if (strcmp(name, "number") == 0)
+ return PyLong_FromLong((long) get_tab_number(this->tab));
+ else if (strcmp(name, "vars") == 0)
+ return DictionaryNew(this->tab->tp_vars);
+ else if (strcmp(name, "window") == 0)
+ {
+ /* For current tab window.c does not bother to set or update tp_curwin
+ */
+ if (this->tab == curtab)
+ return WindowNew(curwin);
+ else
+ return WindowNew(this->tab->tp_curwin);
+ }
+ return NULL;
+}
+
+ static PyObject *
+TabPageRepr(PyObject *self)
+{
+ static char repr[100];
+ TabPageObject *this = (TabPageObject *)(self);
+
+ if (this->tab == INVALID_TABPAGE_VALUE)
+ {
+ vim_snprintf(repr, 100, _("<tabpage object (deleted) at %p>"), (self));
+ return PyString_FromString(repr);
+ }
+ else
+ {
+ int t = get_tab_number(this->tab);
+
+ if (t == 0)
+ vim_snprintf(repr, 100, _("<tabpage object (unknown) at %p>"),
+ (self));
+ else
+ vim_snprintf(repr, 100, _("<tabpage %d>"), t - 1);
+
+ return PyString_FromString(repr);
+ }
+}
+
+static struct PyMethodDef TabPageMethods[] = {
+ /* name, function, calling, documentation */
+ { NULL, NULL, 0, NULL }
+};
+
+/*
+ * Window list object
+ */
+
+static PyTypeObject TabListType;
+static PySequenceMethods TabListAsSeq;
+
+typedef struct
+{
+ PyObject_HEAD
+} TabListObject;
+
+ static PyInt
+TabListLength(PyObject *self UNUSED)
+{
+ tabpage_T *tp = first_tabpage;
+ PyInt n = 0;
+
+ while (tp != NULL)
+ {
+ ++n;
+ tp = tp->tp_next;
+ }
+
+ return n;
+}
+
+ static PyObject *
+TabListItem(PyObject *self UNUSED, PyInt n)
+{
+ tabpage_T *tp;
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, --n)
+ if (n == 0)
+ return TabPageNew(tp);
+
+ PyErr_SetString(PyExc_IndexError, _("no such tab page"));
+ return NULL;
+}
+
/* Window object
*/
@@ -1588,8 +1738,6 @@ typedef struct
win_T *win;
} WindowObject;
-static int WindowSetattr(PyObject *, char *, PyObject *);
-static PyObject *WindowRepr(PyObject *);
static PyTypeObject WindowType;
static int
@@ -1681,7 +1829,7 @@ WindowAttr(WindowObject *this, char *name)
return OptionsNew(SREQ_WIN, this->win, (checkfun) CheckWindow,
(PyObject *) this);
else if (strcmp(name, "number") == 0)
- return PyLong_FromLong((long) get_win_number(this->win));
+ return PyLong_FromLong((long) get_win_number(this->win, firstwin));
else if (strcmp(name,"__members__") == 0)
return Py_BuildValue("[ssssssss]", "buffer", "cursor", "height", "vars",
"options", "number", "row", "col");
@@ -1797,7 +1945,7 @@ WindowRepr(PyObject *self)
}
else
{
- int w = get_win_number(this->win);
+ int w = get_win_number(this->win, firstwin);
if (w == 0)
vim_snprintf(repr, 100, _("<window object (unknown) at %p>"),
@@ -1824,14 +1972,59 @@ static PySequenceMethods WinListAsSeq;
typedef struct
{
PyObject_HEAD
+ TabPageObject *tabObject;
} WinListObject;
+ static PyObject *
+WinListNew(TabPageObject *tabObject)
+{
+ WinListObject *self;
+
+ self = PyObject_NEW(WinListObject, &WinListType);
+ self->tabObject = tabObject;
+ Py_INCREF(tabObject);
+
+ return (PyObject *)(self);
+}
+
+ static void
+WinListDestructor(PyObject *self)
+{
+ TabPageObject *tabObject = ((WinListObject *)(self))->tabObject;
+
+ if (tabObject)
+ Py_DECREF((PyObject *)(tabObject));
+
+ DESTRUCTOR_FINISH(self);
+}
+
+ static win_T *
+get_firstwin(WinListObject *this)
+{
+ if (this->tabObject)
+ {
+ if (CheckTabPage(this->tabObject))
+ return NULL;
+ /* For current tab window.c does not bother to set or update tp_firstwin
+ */
+ else if (this->tabObject->tab == curtab)
+ return firstwin;
+ else
+ return this->tabObject->tab->tp_firstwin;
+ }
+ else
+ return firstwin;
+}
+
static PyInt
-WinListLength(PyObject *self UNUSED)
+WinListLength(PyObject *self)
{
- win_T *w = firstwin;
+ win_T *w;
PyInt n = 0;
+ if (!(w = get_firstwin((WinListObject *)(self))))
+ return -1;
+
while (w != NULL)
{
++n;
@@ -1842,11 +2035,14 @@ WinListLength(PyObject *self UNUSED)
}
static PyObject *
-WinListItem(PyObject *self UNUSED, PyInt n)
+WinListItem(PyObject *self, PyInt n)
{
win_T *w;
- for (w = firstwin; w != NULL; w = W_NEXT(w), --n)
+ if (!(w = get_firstwin((WinListObject *)(self))))
+ return NULL;
+
+ for (; w != NULL; w = W_NEXT(w), --n)
if (n == 0)
return WindowNew(w);
@@ -3018,12 +3214,15 @@ CurrentGetattr(PyObject *self UNUSED, char *name)
return (PyObject *)BufferNew(curbuf);
else if (strcmp(name, "window") == 0)
return (PyObject *)WindowNew(curwin);
+ else if (strcmp(name, "tabpage") == 0)
+ return (PyObject *)TabPageNew(curtab);
else if (strcmp(name, "line") == 0)
return GetBufferLine(curbuf, (PyInt)curwin->w_cursor.lnum);
else if (strcmp(name, "range") == 0)
return RangeNew(curbuf, RangeStart, RangeEnd);
else if (strcmp(name,"__members__") == 0)
- return Py_BuildValue("[ssss]", "buffer", "window", "line", "range");
+ return Py_BuildValue("[sssss]", "buffer", "window", "line", "range",
+ "tabpage");
else
{
PyErr_SetString(PyExc_AttributeError, name);
@@ -3568,6 +3767,23 @@ init_structs(void)
WindowType.tp_setattr = WindowSetattr;
#endif
+ vim_memset(&TabPageType, 0, sizeof(TabPageType));
+ TabPageType.tp_name = "vim.tabpage";
+ TabPageType.tp_basicsize = sizeof(TabPageObject);
+ TabPageType.tp_dealloc = TabPageDestructor;
+ TabPageType.tp_repr = TabPageRepr;
+ TabPageType.tp_flags = Py_TPFLAGS_DEFAULT;
+ TabPageType.tp_doc = "vim tab page object";
+ TabPageType.tp_methods = TabPageMethods;
+#if PY_MAJOR_VERSION >= 3
+ TabPageType.tp_getattro = TabPageGetattro;
+ TabPageType.tp_alloc = call_PyType_GenericAlloc;
+ TabPageType.tp_new = call_PyType_GenericNew;
+ TabPageType.tp_free = call_PyObject_Free;
+#else
+ TabPageType.tp_getattr = TabPageGetattr;
+#endif
+
vim_memset(&BufMapType, 0, sizeof(BufMapType));
BufMapType.tp_name = "vim.bufferlist";
BufMapType.tp_basicsize = sizeof(BufMapObject);
@@ -3582,6 +3798,14 @@ init_structs(void)
WinListType.tp_as_sequence = &WinListAsSeq;
WinListType.tp_flags = Py_TPFLAGS_DEFAULT;
WinListType.tp_doc = "vim window list";
+ WinListType.tp_dealloc = WinListDestructor;
+
+ vim_memset(&TabListType, 0, sizeof(TabListType));
+ TabListType.tp_name = "vim.tabpagelist";
+ TabListType.tp_basicsize = sizeof(TabListType);
+ TabListType.tp_as_sequence = &TabListAsSeq;
+ TabListType.tp_flags = Py_TPFLAGS_DEFAULT;
+ TabListType.tp_doc = "vim tab page list";
vim_memset(&RangeType, 0, sizeof(RangeType));
RangeType.tp_name = "vim.range";
diff --git a/src/if_python.c b/src/if_python.c
index 575f8220..b756c3c6 100644
--- a/src/if_python.c
+++ b/src/if_python.c
@@ -624,10 +624,12 @@ static int initialised = 0;
#define WIN_PYTHON_REF(win) win->w_python_ref
#define BUF_PYTHON_REF(buf) buf->b_python_ref
+#define TAB_PYTHON_REF(tab) tab->tp_python_ref
static PyObject *OutputGetattr(PyObject *, char *);
static PyObject *BufferGetattr(PyObject *, char *);
static PyObject *WindowGetattr(PyObject *, char *);
+static PyObject *TabPageGetattr(PyObject *, char *);
static PyObject *RangeGetattr(PyObject *, char *);
static PyObject *DictionaryGetattr(PyObject *, char*);
static PyObject *ListGetattr(PyObject *, char *);
@@ -1137,6 +1139,24 @@ RangeAssSlice(PyObject *self, PyInt lo, PyInt hi, PyObject *val)
&((RangeObject *)(self))->end);
}
+/* TabPage object - Implementation
+ */
+
+ static PyObject *
+TabPageGetattr(PyObject *self, char *name)
+{
+ PyObject *r;
+
+ if (CheckTabPage((TabPageObject *)(self)))
+ return NULL;
+
+ r = TabPageAttr((TabPageObject *)(self), name);
+ if (r || PyErr_Occurred())
+ return r;
+ else
+ return Py_FindMethod(TabPageMethods, self, name);
+}
+
/* Window object - Implementation
*/
@@ -1155,6 +1175,24 @@ WindowGetattr(PyObject *self, char *name)
return Py_FindMethod(WindowMethods, self, name);
}
+/* Tab page list object - Definitions
+ */
+
+static PySequenceMethods TabListAsSeq = {
+ (PyInquiry) TabListLength, /* sq_length, len(x) */
+ (binaryfunc) 0, /* sq_concat, x+y */
+ (PyIntArgFunc) 0, /* sq_repeat, x*n */
+ (PyIntArgFunc) TabListItem, /* 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 list object - Definitions
*/
@@ -1198,6 +1236,17 @@ python_window_free(win_T *win)
WIN_PYTHON_REF(win) = NULL;
}
}
+
+ void
+python_tabpage_free(tabpage_T *tab)
+{
+ if (TAB_PYTHON_REF(tab) != NULL)
+ {
+ TabPageObject *tp = TAB_PYTHON_REF(tab);
+ tp->tab = INVALID_TABPAGE_VALUE;
+ TAB_PYTHON_REF(tab) = NULL;
+ }
+}
#endif
static BufMapObject TheBufferMap =
@@ -1208,6 +1257,7 @@ static BufMapObject TheBufferMap =
static WinListObject TheWindowList =
{
PyObject_HEAD_INIT(&WinListType)
+ NULL
};
static CurrentObject TheCurrent =
@@ -1215,6 +1265,11 @@ static CurrentObject TheCurrent =
PyObject_HEAD_INIT(&CurrentType)
};
+static TabListObject TheTabPageList =
+{
+ PyObject_HEAD_INIT(&TabListType)
+};
+
static int
PythonMod_Init(void)
{
@@ -1229,8 +1284,10 @@ PythonMod_Init(void)
PyType_Ready(&BufferType);
PyType_Ready(&RangeType);
PyType_Ready(&WindowType);
+ PyType_Ready(&TabPageType);
PyType_Ready(&BufMapType);
PyType_Ready(&WinListType);
+ PyType_Ready(&TabListType);
PyType_Ready(&CurrentType);
PyType_Ready(&OptionsType);
@@ -1246,6 +1303,7 @@ PythonMod_Init(void)
PyDict_SetItemString(dict, "buffers", (PyObject *)(void *)&TheBufferMap);
PyDict_SetItemString(dict, "current", (PyObject *)(void *)&TheCurrent);
PyDict_SetItemString(dict, "windows", (PyObject *)(void *)&TheWindowList);
+ PyDict_SetItemString(dict, "tabpages", (PyObject *)(void *)&TheTabPageList);
tmp = DictionaryNew(&globvardict);
PyDict_SetItemString(dict, "vars", tmp);
Py_DECREF(tmp);
diff --git a/src/if_python3.c b/src/if_python3.c
index 477c367e..f32aca40 100644
--- a/src/if_python3.c
+++ b/src/if_python3.c
@@ -626,6 +626,7 @@ static int py3initialised = 0;
#define WIN_PYTHON_REF(win) win->w_python3_ref
#define BUF_PYTHON_REF(buf) buf->b_python3_ref
+#define TAB_PYTHON_REF(tab) tab->tp_python3_ref
static void
call_PyObject_Free(void *p)
@@ -652,6 +653,7 @@ call_PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
static PyObject *OutputGetattro(PyObject *, PyObject *);
static int OutputSetattro(PyObject *, PyObject *, PyObject *);
static PyObject *BufferGetattro(PyObject *, PyObject *);
+static PyObject *TabPageGetattro(PyObject *, PyObject *);
static PyObject *WindowGetattro(PyObject *, PyObject *);
static int WindowSetattro(PyObject *, PyObject *, PyObject *);
static PyObject *RangeGetattro(PyObject *, PyObject *);
@@ -1275,6 +1277,26 @@ RangeAsSubscript(PyObject *self, PyObject *idx, PyObject *val)
}
}
+/* TabPage object - Implementation
+ */
+
+ static PyObject *
+TabPageGetattro(PyObject *self, PyObject *nameobj)
+{
+ PyObject *r;
+
+ GET_ATTR_STRING(name, nameobj);
+
+ if (CheckTabPage((TabPageObject *)(self)))
+ return NULL;
+
+ r = TabPageAttr((TabPageObject *)(self), name);
+ if (r || PyErr_Occurred())
+ return r;
+ else
+ return PyObject_GenericGetAttr(self, nameobj);
+}
+
/* Window object - Implementation
*/
@@ -1303,6 +1325,22 @@ WindowSetattro(PyObject *self, PyObject *nameobj, PyObject *val)
return WindowSetattr(self, name, val);
}
+/* Tab page list object - Definitions
+ */
+
+static PySequenceMethods TabListAsSeq = {
+ (lenfunc) TabListLength, /* sq_length, len(x) */
+ (binaryfunc) 0, /* sq_concat, x+y */
+ (ssizeargfunc) 0, /* sq_repeat, x*n */
+ (ssizeargfunc) TabListItem, /* sq_item, x[i] */
+ 0, /* 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 list object - Definitions
*/
@@ -1497,6 +1535,17 @@ python3_window_free(win_T *win)
WIN_PYTHON_REF(win) = NULL;
}
}
+
+ void
+python3_tabpage_free(tabpage_T *tab)
+{
+ if (TAB_PYTHON_REF(tab) != NULL)
+ {
+ TabPageObject *tp = TAB_PYTHON_REF(tab);
+ tp->tab = INVALID_TABPAGE_VALUE;
+ TAB_PYTHON_REF(tab) = NULL;
+ }
+}
#endif
static BufMapObject TheBufferMap =
@@ -1507,6 +1556,7 @@ static BufMapObject TheBufferMap =
static WinListObject TheWindowList =
{
PyObject_HEAD_INIT(&WinListType)
+ NULL
};
static CurrentObject TheCurrent =
@@ -1514,6 +1564,11 @@ static CurrentObject TheCurrent =
PyObject_HEAD_INIT(&CurrentType)
};
+static TabListObject TheTabPageList =
+{
+ PyObject_HEAD_INIT(&TabListType)
+};
+
static PyObject *
Py3Init_vim(void)
{
@@ -1526,8 +1581,10 @@ Py3Init_vim(void)
PyType_Ready(&BufferType);
PyType_Ready(&RangeType);
PyType_Ready(&WindowType);
+ PyType_Ready(&TabPageType);
PyType_Ready(&BufMapType);
PyType_Ready(&WinListType);
+ PyType_Ready(&TabListType);
PyType_Ready(&CurrentType);
PyType_Ready(&DictionaryType);
PyType_Ready(&ListType);
@@ -1551,6 +1608,8 @@ Py3Init_vim(void)
PyModule_AddObject(mod, "current", (PyObject *)(void *)&TheCurrent);
Py_INCREF((PyObject *)(void *)&TheWindowList);
PyModule_AddObject(mod, "windows", (PyObject *)(void *)&TheWindowList);
+ Py_INCREF((PyObject *)(void *)&TheTabPageList);
+ PyModule_AddObject(mod, "tabpages", (PyObject *)(void *)&TheTabPageList);
PyModule_AddObject(mod, "vars", DictionaryNew(&globvardict));
PyModule_AddObject(mod, "vvars", DictionaryNew(&vimvardict));
diff --git a/src/proto/if_python.pro b/src/proto/if_python.pro
index 370c5956..4ba977cf 100644
--- a/src/proto/if_python.pro
+++ b/src/proto/if_python.pro
@@ -6,6 +6,7 @@ void ex_python __ARGS((exarg_T *eap));
void ex_pyfile __ARGS((exarg_T *eap));
void python_buffer_free __ARGS((buf_T *buf));
void python_window_free __ARGS((win_T *win));
+void python_tabpage_free __ARGS((tabpage_T *tab));
void do_pyeval __ARGS((char_u *str, typval_T *rettv));
void set_ref_in_python __ARGS((int copyID));
/* vim: set ft=c : */
diff --git a/src/proto/if_python3.pro b/src/proto/if_python3.pro
index d402ecb4..74b2be4b 100644
--- a/src/proto/if_python3.pro
+++ b/src/proto/if_python3.pro
@@ -6,6 +6,7 @@ void ex_py3 __ARGS((exarg_T *eap));
void ex_py3file __ARGS((exarg_T *eap));
void python3_buffer_free __ARGS((buf_T *buf));
void python3_window_free __ARGS((win_T *win));
+void python3_tabpage_free __ARGS((tabpage_T *tab));
void do_py3eval __ARGS((char_u *str, typval_T *rettv));
void set_ref_in_python3 __ARGS((int copyID));
/* vim: set ft=c : */
diff --git a/src/proto/window.pro b/src/proto/window.pro
index a77da59c..a7fcf0c8 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -74,5 +74,6 @@ int match_add __ARGS((win_T *wp, char_u *grp, char_u *pat, int prio, int id));
int match_delete __ARGS((win_T *wp, int id, int perr));
void clear_matches __ARGS((win_T *wp));
matchitem_T *get_match __ARGS((win_T *wp, int id));
-int get_win_number __ARGS((win_T *wp));
+int get_win_number __ARGS((win_T *wp, win_T *first_win));
+int get_tab_number __ARGS((tabpage_T *tp));
/* vim: set ft=c : */
diff --git a/src/structs.h b/src/structs.h
index 5db77209..e84a2b61 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1759,6 +1759,14 @@ struct tabpage_S
dictitem_T tp_winvar; /* variable for "t:" Dictionary */
dict_T *tp_vars; /* internal variables, local to tab page */
#endif
+
+#ifdef FEAT_PYTHON
+ void *tp_python_ref; /* The Python value for this tab page */
+#endif
+
+#ifdef FEAT_PYTHON3
+ void *tp_python3_ref; /* The Python value for this tab page */
+#endif
};
/*
diff --git a/src/version.c b/src/version.c
index a6ebcab2..6c41c464 100644
--- 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 */
/**/
+ 949,
+/**/
948,
/**/
947,
diff --git a/src/window.c b/src/window.c
index 03547149..bbd8d1e5 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3510,6 +3510,15 @@ free_tabpage(tp)
hash_init(&tp->tp_vars->dv_hashtab);
unref_var_dict(tp->tp_vars);
#endif
+
+#ifdef FEAT_PYTHON
+ python_tabpage_free(tp);
+#endif
+
+#ifdef FEAT_PYTHON3
+ python3_tabpage_free(tp);
+#endif
+
vim_free(tp);
}
@@ -6734,12 +6743,12 @@ get_match(wp, id)
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3) || defined(PROTO)
int
-get_win_number(win_T *wp)
+get_win_number(win_T *wp, win_T *first_win)
{
int i = 1;
win_T *w;
- for (w = firstwin; w != NULL && w != wp; w = W_NEXT(w))
+ for (w = first_win; w != NULL && w != wp; w = W_NEXT(w))
++i;
if (w == NULL)
@@ -6747,4 +6756,19 @@ get_win_number(win_T *wp)
else
return i;
}
+
+ int
+get_tab_number(tabpage_T *tp)
+{
+ int i = 1;
+ tabpage_T *t;
+
+ for (t = first_tabpage; t != NULL && t != tp; t = t->tp_next)
+ ++i;
+
+ if (t == NULL)
+ return 0;
+ else
+ return i;
+}
#endif