0
0
mirror of https://github.com/vim/vim.git synced 2025-09-26 04:04:07 -04:00

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
@@ -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
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
values are different: "4 == '4'" is true, "4 is '4'" is false and "0 is []" is
false and not an error. "is#"/"isnot#" and "is?"/"isnot?" can be used to match
and ignore case.
values are different: >
echo 4 == '4'
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,
and the comparison is done on Numbers. This means that "0 == 'x'" is TRUE,
because 'x' converted to a Number is zero.
and the comparison is done on Numbers. This means that: >
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
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
visualmode( [expr]) String last visual mode used
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}
wincol() Number window column of the cursor
winheight( {nr}) Number height of window {nr}
@@ -7162,6 +7176,29 @@ wildmenumode() *wildmenumode()*
(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({nr}) The result is a Number, which is the number of the buffer
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 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},
@@ -12661,6 +12668,43 @@ f_getwinposx(typval_T *argvars UNUSED, typval_T *rettv)
#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
*/

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_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);

View File

@@ -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 : */

View File

@@ -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!) */

View File

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

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[] =
{ /* Add new patch number below this line */
/**/
1557,
/**/
1556,
/**/

View File

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