1
0
forked from aniani/vim

patch 7.4.1557

Problem:    Windows cannot be identified.
Solution:   Add a unique window number to each window and functions to use it.
This commit is contained in:
Bram Moolenaar
2016-03-13 18:07:30 +01:00
parent a3442cb505
commit 86edef664e
9 changed files with 270 additions and 8 deletions

View File

@@ -1,4 +1,4 @@
*eval.txt* For Vim version 7.4. Last change: 2016 Mar 12 *eval.txt* For Vim version 7.4. Last change: 2016 Mar 13
VIM REFERENCE MANUAL by Bram Moolenaar VIM REFERENCE MANUAL by Bram Moolenaar
@@ -764,13 +764,23 @@ expressions are referring to the same |List| or |Dictionary| instance. A copy
of a |List| is different from the original |List|. When using "is" without of a |List| is different from the original |List|. When using "is" without
a |List| or a |Dictionary| it is equivalent to using "equal", using "isnot" a |List| or a |Dictionary| it is equivalent to using "equal", using "isnot"
equivalent to using "not equal". Except that a different type means the equivalent to using "not equal". Except that a different type means the
values are different: "4 == '4'" is true, "4 is '4'" is false and "0 is []" is values are different: >
false and not an error. "is#"/"isnot#" and "is?"/"isnot?" can be used to match echo 4 == '4'
and ignore case. 1
echo 4 is '4'
0
echo 0 is []
0
"is#"/"isnot#" and "is?"/"isnot?" can be used to match and ignore case.
When comparing a String with a Number, the String is converted to a Number, When comparing a String with a Number, the String is converted to a Number,
and the comparison is done on Numbers. This means that "0 == 'x'" is TRUE, and the comparison is done on Numbers. This means that: >
because 'x' converted to a Number is zero. echo 0 == 'x'
1
because 'x' converted to a Number is zero. However: >
echo [0] == ['x']
0
Inside a List or Dictionary this conversion is not used.
When comparing two Strings, this is done with strcmp() or stricmp(). This When comparing two Strings, this is done with strcmp() or stricmp(). This
results in the mathematical difference (comparing byte values), not results in the mathematical difference (comparing byte values), not
@@ -2139,6 +2149,10 @@ values( {dict}) List values in {dict}
virtcol( {expr}) Number screen column of cursor or mark virtcol( {expr}) Number screen column of cursor or mark
visualmode( [expr]) String last visual mode used visualmode( [expr]) String last visual mode used
wildmenumode() Number whether 'wildmenu' mode is active wildmenumode() Number whether 'wildmenu' mode is active
win_getid( [{win} [, {tab}]]) Number get window ID for {win} in {tab}
win_gotoid( {expr}) Number go to window with ID {expr}
win_id2tabwin( {expr}) List get tab and window nr from window ID
win_id2win( {expr}) Number get window nr from window ID
winbufnr( {nr}) Number buffer number of window {nr} winbufnr( {nr}) Number buffer number of window {nr}
wincol() Number window column of the cursor wincol() Number window column of the cursor
winheight( {nr}) Number height of window {nr} winheight( {nr}) Number height of window {nr}
@@ -7162,6 +7176,29 @@ wildmenumode() *wildmenumode()*
(Note, this needs the 'wildcharm' option set appropriately). (Note, this needs the 'wildcharm' option set appropriately).
win_getid([{win} [, {tab}]]) *win_getid()*
Get the window ID for the specified window.
When {win} is missing use the current window.
With {win} this is the window number. The top window has
number 1.
Without {tab} use the current tab, otherwise the tab with
number {tab}. The first tab has number one.
Return zero if the window cannot be found.
win_gotoid({expr}) *win_gotoid()*
Go to window with ID {expr}. This may also change the current
tabpage.
Return 1 if successful, 0 if the window cannot be found.
win_id2tabwin({expr} *win_id2tabwin()*
Return a list with the tab number and window number of window
with ID {expr}: [tabnr, winnr].
Return [0, 0] if the window cannot be found.
win_id2win({expr}) *win_id2win()*
Return the window number of window with ID {expr}.
Return 0 if the window cannot be found in the current tabpage.
*winbufnr()* *winbufnr()*
winbufnr({nr}) The result is a Number, which is the number of the buffer winbufnr({nr}) The result is a Number, which is the number of the buffer
associated with window {nr}. When {nr} is zero, the number of associated with window {nr}. When {nr} is zero, the number of

View File

@@ -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 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_find_nr(list_T *l, long idx, int *errorp);
static long list_idx_of_item(list_T *l, listitem_T *item); 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_extend(list_T *l1, list_T *l2, listitem_T *bef);
static int list_concat(list_T *l1, list_T *l2, typval_T *tv); 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); 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_virtcol(typval_T *argvars, typval_T *rettv);
static void f_visualmode(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_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_winbufnr(typval_T *argvars, typval_T *rettv);
static void f_wincol(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); 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". * Append "n" to list "l".
* Returns FAIL when out of memory. * Returns FAIL when out of memory.
*/ */
static int int
list_append_number(list_T *l, varnumber_T n) list_append_number(list_T *l, varnumber_T n)
{ {
listitem_T *li; listitem_T *li;
@@ -8385,6 +8388,10 @@ static struct fst
{"virtcol", 1, 1, f_virtcol}, {"virtcol", 1, 1, f_virtcol},
{"visualmode", 0, 1, f_visualmode}, {"visualmode", 0, 1, f_visualmode},
{"wildmenumode", 0, 0, f_wildmenumode}, {"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}, {"winbufnr", 1, 1, f_winbufnr},
{"wincol", 0, 0, f_wincol}, {"wincol", 0, 0, f_wincol},
{"winheight", 1, 1, f_winheight}, {"winheight", 1, 1, f_winheight},
@@ -12661,6 +12668,43 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
#endif #endif
} }
/*
* "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 * "getwinposy()" function
*/ */

View File

@@ -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_tv(list_T *l, typval_T *tv);
int list_append_dict(list_T *list, dict_T *dict); 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_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); 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 list_insert(list_T *l, listitem_T *ni, listitem_T *item);
void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2); void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);

View File

@@ -83,4 +83,8 @@ void clear_matches(win_T *wp);
matchitem_T *get_match(win_T *wp, int id); matchitem_T *get_match(win_T *wp, int id);
int get_win_number(win_T *wp, win_T *first_win); int get_win_number(win_T *wp, win_T *first_win);
int get_tab_number(tabpage_T *tp); 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 : */ /* vim: set ft=c : */

View File

@@ -2273,6 +2273,8 @@ struct matchitem
*/ */
struct window_S struct window_S
{ {
int w_id; /* unique window ID */
buf_T *w_buffer; /* buffer we are a window into (used buf_T *w_buffer; /* buffer we are a window into (used
often, keep it the first item!) */ often, keep it the first item!) */

View File

@@ -186,6 +186,7 @@ NEW_TESTS = test_arglist.res \
test_viminfo.res \ test_viminfo.res \
test_viml.res \ test_viml.res \
test_visual.res \ test_visual.res \
test_window_id.res \
test_alot.res test_alot.res

View File

@@ -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

View File

@@ -743,6 +743,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
1557,
/**/ /**/
1556, 1556,
/**/ /**/

View File

@@ -4541,6 +4541,8 @@ buf_jump_open_tab(buf_T *buf)
} }
#endif #endif
static int last_win_id = 0;
/* /*
* Allocate a window structure and link it in the window list when "hidden" is * Allocate a window structure and link it in the window list when "hidden" is
* FALSE. * FALSE.
@@ -4563,6 +4565,8 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED)
return NULL; return NULL;
} }
new_wp->w_id = ++last_win_id;
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
/* init w: variables */ /* init w: variables */
new_wp->w_vars = dict_alloc(); new_wp->w_vars = dict_alloc();
@@ -7198,3 +7202,99 @@ frame_check_width(frame_T *topfrp, int width)
} }
#endif #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