summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/eval.c48
-rw-r--r--src/proto/eval.pro1
-rw-r--r--src/proto/window.pro4
-rw-r--r--src/structs.h2
-rw-r--r--src/testdir/Make_all.mak1
-rw-r--r--src/testdir/test_window_id.vim71
-rw-r--r--src/version.c2
-rw-r--r--src/window.c100
8 files changed, 227 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c
index 0b589fdc0..5025a52c1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -434,7 +434,6 @@ static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
static long list_find_nr(list_T *l, long idx, int *errorp);
static long list_idx_of_item(list_T *l, listitem_T *item);
-static int list_append_number(list_T *l, varnumber_T n);
static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
static list_T *list_copy(list_T *orig, int deep, int copyID);
@@ -808,6 +807,10 @@ static void f_values(typval_T *argvars, typval_T *rettv);
static void f_virtcol(typval_T *argvars, typval_T *rettv);
static void f_visualmode(typval_T *argvars, typval_T *rettv);
static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
+static void f_win_getid(typval_T *argvars, typval_T *rettv);
+static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
+static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
+static void f_win_id2win(typval_T *argvars, typval_T *rettv);
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
static void f_wincol(typval_T *argvars, typval_T *rettv);
static void f_winheight(typval_T *argvars, typval_T *rettv);
@@ -6469,7 +6472,7 @@ list_append_string(list_T *l, char_u *str, int len)
* Append "n" to list "l".
* Returns FAIL when out of memory.
*/
- static int
+ int
list_append_number(list_T *l, varnumber_T n)
{
listitem_T *li;
@@ -8385,6 +8388,10 @@ static struct fst
{"virtcol", 1, 1, f_virtcol},
{"visualmode", 0, 1, f_visualmode},
{"wildmenumode", 0, 0, f_wildmenumode},
+ {"win_getid", 0, 2, f_win_getid},
+ {"win_gotoid", 1, 1, f_win_gotoid},
+ {"win_id2tabwin", 1, 1, f_win_id2tabwin},
+ {"win_id2win", 1, 1, f_win_id2win},
{"winbufnr", 1, 1, f_winbufnr},
{"wincol", 0, 0, f_wincol},
{"winheight", 1, 1, f_winheight},
@@ -12662,6 +12669,43 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
}
/*
+ * "win_getid()" function
+ */
+ static void
+f_win_getid(typval_T *argvars, typval_T *rettv)
+{
+ rettv->vval.v_number = win_getid(argvars);
+}
+
+/*
+ * "win_gotoid()" function
+ */
+ static void
+f_win_gotoid(typval_T *argvars, typval_T *rettv)
+{
+ rettv->vval.v_number = win_gotoid(argvars);
+}
+
+/*
+ * "win_id2tabwin()" function
+ */
+ static void
+f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
+{
+ if (rettv_list_alloc(rettv) != FAIL)
+ win_id2tabwin(argvars, rettv->vval.v_list);
+}
+
+/*
+ * "win_id2win()" function
+ */
+ static void
+f_win_id2win(typval_T *argvars, typval_T *rettv)
+{
+ rettv->vval.v_number = win_id2win(argvars);
+}
+
+/*
* "getwinposy()" function
*/
static void
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index f5e0d1950..7035f26e2 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -59,6 +59,7 @@ void list_append(list_T *l, listitem_T *item);
int list_append_tv(list_T *l, typval_T *tv);
int list_append_dict(list_T *list, dict_T *dict);
int list_append_string(list_T *l, char_u *str, int len);
+int list_append_number(list_T *l, varnumber_T n);
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 613fe219b..3c511e3c5 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -83,4 +83,8 @@ void clear_matches(win_T *wp);
matchitem_T *get_match(win_T *wp, int id);
int get_win_number(win_T *wp, win_T *first_win);
int get_tab_number(tabpage_T *tp);
+int win_getid(typval_T *argvars);
+int win_gotoid(typval_T *argvars);
+void win_id2tabwin(typval_T *argvars, list_T *list);
+int win_id2win(typval_T *argvars);
/* vim: set ft=c : */
diff --git a/src/structs.h b/src/structs.h
index 6bf21263a..4aa7415f0 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -2273,6 +2273,8 @@ struct matchitem
*/
struct window_S
{
+ int w_id; /* unique window ID */
+
buf_T *w_buffer; /* buffer we are a window into (used
often, keep it the first item!) */
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 5ad1718c6..233ca12df 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -186,6 +186,7 @@ NEW_TESTS = test_arglist.res \
test_viminfo.res \
test_viml.res \
test_visual.res \
+ test_window_id.res \
test_alot.res
diff --git a/src/testdir/test_window_id.vim b/src/testdir/test_window_id.vim
new file mode 100644
index 000000000..b9e9f45c4
--- /dev/null
+++ b/src/testdir/test_window_id.vim
@@ -0,0 +1,71 @@
+" Test using the window ID.
+
+func Test_win_getid()
+ edit one
+ let id1 = win_getid()
+ split two
+ let id2 = win_getid()
+ split three
+ let id3 = win_getid()
+ tabnew
+ edit four
+ let id4 = win_getid()
+ split five
+ let id5 = win_getid()
+ tabnext
+
+ wincmd w
+ call assert_equal("two", expand("%"))
+ call assert_equal(id2, win_getid())
+ let nr2 = winnr()
+ wincmd w
+ call assert_equal("one", expand("%"))
+ call assert_equal(id1, win_getid())
+ let nr1 = winnr()
+ wincmd w
+ call assert_equal("three", expand("%"))
+ call assert_equal(id3, win_getid())
+ let nr3 = winnr()
+ tabnext
+ call assert_equal("five", expand("%"))
+ call assert_equal(id5, win_getid())
+ let nr5 = winnr()
+ wincmd w
+ call assert_equal("four", expand("%"))
+ call assert_equal(id4, win_getid())
+ let nr4 = winnr()
+ tabnext
+
+ exe nr1 . "wincmd w"
+ call assert_equal(id1, win_getid())
+ exe nr2 . "wincmd w"
+ call assert_equal(id2, win_getid())
+ exe nr3 . "wincmd w"
+ call assert_equal(id3, win_getid())
+ tabnext
+ exe nr4 . "wincmd w"
+ call assert_equal(id4, win_getid())
+ exe nr5 . "wincmd w"
+ call assert_equal(id5, win_getid())
+
+ call win_gotoid(id2)
+ call assert_equal("two", expand("%"))
+ call win_gotoid(id4)
+ call assert_equal("four", expand("%"))
+ call win_gotoid(id1)
+ call assert_equal("one", expand("%"))
+ call win_gotoid(id5)
+ call assert_equal("five", expand("%"))
+
+ call assert_equal(0, win_id2win(9999))
+ call assert_equal(nr5, win_id2win(id5))
+ call assert_equal(0, win_id2win(id1))
+ tabnext
+ call assert_equal(nr1, win_id2win(id1))
+
+ call assert_equal([0, 0], win_id2tabwin(9999))
+ call assert_equal([1, nr2], win_id2tabwin(id2))
+ call assert_equal([2, nr4], win_id2tabwin(id4))
+
+ only!
+endfunc
diff --git a/src/version.c b/src/version.c
index 9c15aafc8..bed7a4604 100644
--- a/src/version.c
+++ b/src/version.c
@@ -744,6 +744,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1557,
+/**/
1556,
/**/
1555,
diff --git a/src/window.c b/src/window.c
index 7dfbe5a99..b6111bd15 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4541,6 +4541,8 @@ buf_jump_open_tab(buf_T *buf)
}
#endif
+static int last_win_id = 0;
+
/*
* Allocate a window structure and link it in the window list when "hidden" is
* FALSE.
@@ -4563,6 +4565,8 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED)
return NULL;
}
+ new_wp->w_id = ++last_win_id;
+
#ifdef FEAT_EVAL
/* init w: variables */
new_wp->w_vars = dict_alloc();
@@ -7198,3 +7202,99 @@ frame_check_width(frame_T *topfrp, int width)
}
#endif
+#if defined(FEAT_EVAL) || defined(PROTO)
+ int
+win_getid(typval_T *argvars)
+{
+ int winnr;
+ win_T *wp;
+
+ if (argvars[0].v_type == VAR_UNKNOWN)
+ return curwin->w_id;
+ winnr = get_tv_number(&argvars[0]);
+ if (winnr > 0)
+ {
+ if (argvars[1].v_type == VAR_UNKNOWN)
+ wp = firstwin;
+ else
+ {
+ tabpage_T *tp;
+ int tabnr = get_tv_number(&argvars[1]);
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ if (--tabnr == 0)
+ break;
+ if (tp == NULL)
+ return -1;
+ wp = tp->tp_firstwin;
+ }
+ for ( ; wp != NULL; wp = wp->w_next)
+ if (--winnr == 0)
+ return wp->w_id;
+ }
+ return 0;
+}
+
+ int
+win_gotoid(typval_T *argvars)
+{
+ win_T *wp;
+ tabpage_T *tp;
+ int id = get_tv_number(&argvars[0]);
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
+ wp != NULL; wp = wp->w_next)
+ if (wp->w_id == id)
+ {
+ goto_tabpage_win(tp, wp);
+ return 1;
+ }
+ return 0;
+}
+
+ void
+win_id2tabwin(typval_T *argvars, list_T *list)
+{
+ win_T *wp;
+ tabpage_T *tp;
+ int winnr = 1;
+ int tabnr = 1;
+ int id = get_tv_number(&argvars[0]);
+
+ for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
+ {
+ for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
+ wp != NULL; wp = wp->w_next)
+ {
+ if (wp->w_id == id)
+ {
+ list_append_number(list, tabnr);
+ list_append_number(list, winnr);
+ return;
+ }
+ ++winnr;
+ }
+ ++tabnr;
+ winnr = 1;
+ }
+ list_append_number(list, 0);
+ list_append_number(list, 0);
+}
+
+ int
+win_id2win(typval_T *argvars)
+{
+ win_T *wp;
+ int nr = 1;
+ int id = get_tv_number(&argvars[0]);
+
+ for (wp = firstwin; wp != NULL; wp = wp->w_next)
+ {
+ if (wp->w_id == id)
+ return nr;
+ ++nr;
+ }
+ return 0;
+}
+#endif