Skip to content

Commit 86edef6

Browse files
committed
patch 7.4.1557
Problem: Windows cannot be identified. Solution: Add a unique window number to each window and functions to use it.
1 parent a3442cb commit 86edef6

9 files changed

Lines changed: 270 additions & 8 deletions

File tree

runtime/doc/eval.txt

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 12
1+
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 13
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -764,13 +764,23 @@ expressions are referring to the same |List| or |Dictionary| instance. A copy
764764
of a |List| is different from the original |List|. When using "is" without
765765
a |List| or a |Dictionary| it is equivalent to using "equal", using "isnot"
766766
equivalent to using "not equal". Except that a different type means the
767-
values are different: "4 == '4'" is true, "4 is '4'" is false and "0 is []" is
768-
false and not an error. "is#"/"isnot#" and "is?"/"isnot?" can be used to match
769-
and ignore case.
767+
values are different: >
768+
echo 4 == '4'
769+
1
770+
echo 4 is '4'
771+
0
772+
echo 0 is []
773+
0
774+
"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
770775

771776
When comparing a String with a Number, the String is converted to a Number,
772-
and the comparison is done on Numbers. This means that "0 == 'x'" is TRUE,
773-
because 'x' converted to a Number is zero.
777+
and the comparison is done on Numbers. This means that: >
778+
echo 0 == 'x'
779+
1
780+
because 'x' converted to a Number is zero. However: >
781+
echo [0] == ['x']
782+
0
783+
Inside a List or Dictionary this conversion is not used.
774784

775785
When comparing two Strings, this is done with strcmp() or stricmp(). This
776786
results in the mathematical difference (comparing byte values), not
@@ -2139,6 +2149,10 @@ values( {dict}) List values in {dict}
21392149
virtcol( {expr}) Number screen column of cursor or mark
21402150
visualmode( [expr]) String last visual mode used
21412151
wildmenumode() Number whether 'wildmenu' mode is active
2152+
win_getid( [{win} [, {tab}]]) Number get window ID for {win} in {tab}
2153+
win_gotoid( {expr}) Number go to window with ID {expr}
2154+
win_id2tabwin( {expr}) List get tab and window nr from window ID
2155+
win_id2win( {expr}) Number get window nr from window ID
21422156
winbufnr( {nr}) Number buffer number of window {nr}
21432157
wincol() Number window column of the cursor
21442158
winheight( {nr}) Number height of window {nr}
@@ -7162,6 +7176,29 @@ wildmenumode() *wildmenumode()*
71627176
(Note, this needs the 'wildcharm' option set appropriately).
71637177

71647178

7179+
win_getid([{win} [, {tab}]]) *win_getid()*
7180+
Get the window ID for the specified window.
7181+
When {win} is missing use the current window.
7182+
With {win} this is the window number. The top window has
7183+
number 1.
7184+
Without {tab} use the current tab, otherwise the tab with
7185+
number {tab}. The first tab has number one.
7186+
Return zero if the window cannot be found.
7187+
7188+
win_gotoid({expr}) *win_gotoid()*
7189+
Go to window with ID {expr}. This may also change the current
7190+
tabpage.
7191+
Return 1 if successful, 0 if the window cannot be found.
7192+
7193+
win_id2tabwin({expr} *win_id2tabwin()*
7194+
Return a list with the tab number and window number of window
7195+
with ID {expr}: [tabnr, winnr].
7196+
Return [0, 0] if the window cannot be found.
7197+
7198+
win_id2win({expr}) *win_id2win()*
7199+
Return the window number of window with ID {expr}.
7200+
Return 0 if the window cannot be found in the current tabpage.
7201+
71657202
*winbufnr()*
71667203
winbufnr({nr}) The result is a Number, which is the number of the buffer
71677204
associated with window {nr}. When {nr} is zero, the number of

src/eval.c

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,6 @@ static int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
434434
static int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
435435
static long list_find_nr(list_T *l, long idx, int *errorp);
436436
static long list_idx_of_item(list_T *l, listitem_T *item);
437-
static int list_append_number(list_T *l, varnumber_T n);
438437
static int list_extend(list_T *l1, list_T *l2, listitem_T *bef);
439438
static int list_concat(list_T *l1, list_T *l2, typval_T *tv);
440439
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);
808807
static void f_virtcol(typval_T *argvars, typval_T *rettv);
809808
static void f_visualmode(typval_T *argvars, typval_T *rettv);
810809
static void f_wildmenumode(typval_T *argvars, typval_T *rettv);
810+
static void f_win_getid(typval_T *argvars, typval_T *rettv);
811+
static void f_win_gotoid(typval_T *argvars, typval_T *rettv);
812+
static void f_win_id2tabwin(typval_T *argvars, typval_T *rettv);
813+
static void f_win_id2win(typval_T *argvars, typval_T *rettv);
811814
static void f_winbufnr(typval_T *argvars, typval_T *rettv);
812815
static void f_wincol(typval_T *argvars, typval_T *rettv);
813816
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)
64696472
* Append "n" to list "l".
64706473
* Returns FAIL when out of memory.
64716474
*/
6472-
static int
6475+
int
64736476
list_append_number(list_T *l, varnumber_T n)
64746477
{
64756478
listitem_T *li;
@@ -8385,6 +8388,10 @@ static struct fst
83858388
{"virtcol", 1, 1, f_virtcol},
83868389
{"visualmode", 0, 1, f_visualmode},
83878390
{"wildmenumode", 0, 0, f_wildmenumode},
8391+
{"win_getid", 0, 2, f_win_getid},
8392+
{"win_gotoid", 1, 1, f_win_gotoid},
8393+
{"win_id2tabwin", 1, 1, f_win_id2tabwin},
8394+
{"win_id2win", 1, 1, f_win_id2win},
83888395
{"winbufnr", 1, 1, f_winbufnr},
83898396
{"wincol", 0, 0, f_wincol},
83908397
{"winheight", 1, 1, f_winheight},
@@ -12661,6 +12668,43 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
1266112668
#endif
1266212669
}
1266312670

12671+
/*
12672+
* "win_getid()" function
12673+
*/
12674+
static void
12675+
f_win_getid(typval_T *argvars, typval_T *rettv)
12676+
{
12677+
rettv->vval.v_number = win_getid(argvars);
12678+
}
12679+
12680+
/*
12681+
* "win_gotoid()" function
12682+
*/
12683+
static void
12684+
f_win_gotoid(typval_T *argvars, typval_T *rettv)
12685+
{
12686+
rettv->vval.v_number = win_gotoid(argvars);
12687+
}
12688+
12689+
/*
12690+
* "win_id2tabwin()" function
12691+
*/
12692+
static void
12693+
f_win_id2tabwin(typval_T *argvars, typval_T *rettv)
12694+
{
12695+
if (rettv_list_alloc(rettv) != FAIL)
12696+
win_id2tabwin(argvars, rettv->vval.v_list);
12697+
}
12698+
12699+
/*
12700+
* "win_id2win()" function
12701+
*/
12702+
static void
12703+
f_win_id2win(typval_T *argvars, typval_T *rettv)
12704+
{
12705+
rettv->vval.v_number = win_id2win(argvars);
12706+
}
12707+
1266412708
/*
1266512709
* "getwinposy()" function
1266612710
*/

src/proto/eval.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void list_append(list_T *l, listitem_T *item);
5959
int list_append_tv(list_T *l, typval_T *tv);
6060
int list_append_dict(list_T *list, dict_T *dict);
6161
int list_append_string(list_T *l, char_u *str, int len);
62+
int list_append_number(list_T *l, varnumber_T n);
6263
int list_insert_tv(list_T *l, typval_T *tv, listitem_T *item);
6364
void list_insert(list_T *l, listitem_T *ni, listitem_T *item);
6465
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);

src/proto/window.pro

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,4 +83,8 @@ void clear_matches(win_T *wp);
8383
matchitem_T *get_match(win_T *wp, int id);
8484
int get_win_number(win_T *wp, win_T *first_win);
8585
int get_tab_number(tabpage_T *tp);
86+
int win_getid(typval_T *argvars);
87+
int win_gotoid(typval_T *argvars);
88+
void win_id2tabwin(typval_T *argvars, list_T *list);
89+
int win_id2win(typval_T *argvars);
8690
/* vim: set ft=c : */

src/structs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2273,6 +2273,8 @@ struct matchitem
22732273
*/
22742274
struct window_S
22752275
{
2276+
int w_id; /* unique window ID */
2277+
22762278
buf_T *w_buffer; /* buffer we are a window into (used
22772279
often, keep it the first item!) */
22782280

src/testdir/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ NEW_TESTS = test_arglist.res \
186186
test_viminfo.res \
187187
test_viml.res \
188188
test_visual.res \
189+
test_window_id.res \
189190
test_alot.res
190191

191192

src/testdir/test_window_id.vim

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
" Test using the window ID.
2+
3+
func Test_win_getid()
4+
edit one
5+
let id1 = win_getid()
6+
split two
7+
let id2 = win_getid()
8+
split three
9+
let id3 = win_getid()
10+
tabnew
11+
edit four
12+
let id4 = win_getid()
13+
split five
14+
let id5 = win_getid()
15+
tabnext
16+
17+
wincmd w
18+
call assert_equal("two", expand("%"))
19+
call assert_equal(id2, win_getid())
20+
let nr2 = winnr()
21+
wincmd w
22+
call assert_equal("one", expand("%"))
23+
call assert_equal(id1, win_getid())
24+
let nr1 = winnr()
25+
wincmd w
26+
call assert_equal("three", expand("%"))
27+
call assert_equal(id3, win_getid())
28+
let nr3 = winnr()
29+
tabnext
30+
call assert_equal("five", expand("%"))
31+
call assert_equal(id5, win_getid())
32+
let nr5 = winnr()
33+
wincmd w
34+
call assert_equal("four", expand("%"))
35+
call assert_equal(id4, win_getid())
36+
let nr4 = winnr()
37+
tabnext
38+
39+
exe nr1 . "wincmd w"
40+
call assert_equal(id1, win_getid())
41+
exe nr2 . "wincmd w"
42+
call assert_equal(id2, win_getid())
43+
exe nr3 . "wincmd w"
44+
call assert_equal(id3, win_getid())
45+
tabnext
46+
exe nr4 . "wincmd w"
47+
call assert_equal(id4, win_getid())
48+
exe nr5 . "wincmd w"
49+
call assert_equal(id5, win_getid())
50+
51+
call win_gotoid(id2)
52+
call assert_equal("two", expand("%"))
53+
call win_gotoid(id4)
54+
call assert_equal("four", expand("%"))
55+
call win_gotoid(id1)
56+
call assert_equal("one", expand("%"))
57+
call win_gotoid(id5)
58+
call assert_equal("five", expand("%"))
59+
60+
call assert_equal(0, win_id2win(9999))
61+
call assert_equal(nr5, win_id2win(id5))
62+
call assert_equal(0, win_id2win(id1))
63+
tabnext
64+
call assert_equal(nr1, win_id2win(id1))
65+
66+
call assert_equal([0, 0], win_id2tabwin(9999))
67+
call assert_equal([1, nr2], win_id2tabwin(id2))
68+
call assert_equal([2, nr4], win_id2tabwin(id4))
69+
70+
only!
71+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,8 @@ static char *(features[]) =
743743

744744
static int included_patches[] =
745745
{ /* Add new patch number below this line */
746+
/**/
747+
1557,
746748
/**/
747749
1556,
748750
/**/

src/window.c

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4541,6 +4541,8 @@ buf_jump_open_tab(buf_T *buf)
45414541
}
45424542
#endif
45434543

4544+
static int last_win_id = 0;
4545+
45444546
/*
45454547
* Allocate a window structure and link it in the window list when "hidden" is
45464548
* FALSE.
@@ -4563,6 +4565,8 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED)
45634565
return NULL;
45644566
}
45654567

4568+
new_wp->w_id = ++last_win_id;
4569+
45664570
#ifdef FEAT_EVAL
45674571
/* init w: variables */
45684572
new_wp->w_vars = dict_alloc();
@@ -7198,3 +7202,99 @@ frame_check_width(frame_T *topfrp, int width)
71987202
}
71997203
#endif
72007204

7205+
#if defined(FEAT_EVAL) || defined(PROTO)
7206+
int
7207+
win_getid(typval_T *argvars)
7208+
{
7209+
int winnr;
7210+
win_T *wp;
7211+
7212+
if (argvars[0].v_type == VAR_UNKNOWN)
7213+
return curwin->w_id;
7214+
winnr = get_tv_number(&argvars[0]);
7215+
if (winnr > 0)
7216+
{
7217+
if (argvars[1].v_type == VAR_UNKNOWN)
7218+
wp = firstwin;
7219+
else
7220+
{
7221+
tabpage_T *tp;
7222+
int tabnr = get_tv_number(&argvars[1]);
7223+
7224+
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
7225+
if (--tabnr == 0)
7226+
break;
7227+
if (tp == NULL)
7228+
return -1;
7229+
wp = tp->tp_firstwin;
7230+
}
7231+
for ( ; wp != NULL; wp = wp->w_next)
7232+
if (--winnr == 0)
7233+
return wp->w_id;
7234+
}
7235+
return 0;
7236+
}
7237+
7238+
int
7239+
win_gotoid(typval_T *argvars)
7240+
{
7241+
win_T *wp;
7242+
tabpage_T *tp;
7243+
int id = get_tv_number(&argvars[0]);
7244+
7245+
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
7246+
for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
7247+
wp != NULL; wp = wp->w_next)
7248+
if (wp->w_id == id)
7249+
{
7250+
goto_tabpage_win(tp, wp);
7251+
return 1;
7252+
}
7253+
return 0;
7254+
}
7255+
7256+
void
7257+
win_id2tabwin(typval_T *argvars, list_T *list)
7258+
{
7259+
win_T *wp;
7260+
tabpage_T *tp;
7261+
int winnr = 1;
7262+
int tabnr = 1;
7263+
int id = get_tv_number(&argvars[0]);
7264+
7265+
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
7266+
{
7267+
for (wp = tp == curtab ? firstwin : tp->tp_firstwin;
7268+
wp != NULL; wp = wp->w_next)
7269+
{
7270+
if (wp->w_id == id)
7271+
{
7272+
list_append_number(list, tabnr);
7273+
list_append_number(list, winnr);
7274+
return;
7275+
}
7276+
++winnr;
7277+
}
7278+
++tabnr;
7279+
winnr = 1;
7280+
}
7281+
list_append_number(list, 0);
7282+
list_append_number(list, 0);
7283+
}
7284+
7285+
int
7286+
win_id2win(typval_T *argvars)
7287+
{
7288+
win_T *wp;
7289+
int nr = 1;
7290+
int id = get_tv_number(&argvars[0]);
7291+
7292+
for (wp = firstwin; wp != NULL; wp = wp->w_next)
7293+
{
7294+
if (wp->w_id == id)
7295+
return nr;
7296+
++nr;
7297+
}
7298+
return 0;
7299+
}
7300+
#endif

0 commit comments

Comments
 (0)