vim-patch:7.4.1557 (#5117)

Problem:    Windows cannot be identified.
Solution:   Add a unique window number to each window and functions to use it.

86edef664e
This commit is contained in:
prollings
2016-08-04 14:22:45 +10:00
committed by Justin M. Keyes
parent 08d11bd42f
commit 0d93cd6c46
7 changed files with 242 additions and 9 deletions

View File

@@ -937,8 +937,9 @@ struct matchitem {
*/
struct window_S {
uint64_t handle;
buf_T *w_buffer; /* buffer we are a window into (used
often, keep it the first item!) */
int w_id; ///< unique window ID
buf_T *w_buffer; ///< buffer we are a window into (used
///< often, keep it the first item!)
synblock_T *w_s; /* for :ownsyntax */

View File

@@ -6987,6 +6987,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 },
@@ -17150,6 +17154,32 @@ static void f_wildmenumode(typval_T *argvars, typval_T *rettv)
rettv->vval.v_number = 1;
}
/// "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);
}
/*
* "winbufnr(nr)" function
*/
@@ -18437,7 +18467,7 @@ static void init_tv(typval_T *varp)
* caller of incompatible types: it sets *denote to TRUE if "denote"
* is not NULL or returns -1 otherwise.
*/
static long get_tv_number(typval_T *varp)
long get_tv_number(typval_T *varp)
{
int error = FALSE;

View File

@@ -39,6 +39,7 @@ NEW_TESTS = \
test_timers.res \
test_viml.res \
test_visual.res \
test_window_id.res \
test_alot.res
SCRIPTS_GUI := test16.out

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

@@ -720,7 +720,7 @@ static int included_patches[] = {
// 1560 NA
// 1559,
// 1558,
// 1557,
1557,
// 1556 NA
// 1555 NA
1554,

View File

@@ -3683,6 +3683,8 @@ win_T *buf_jump_open_tab(buf_T *buf)
return NULL;
}
static int last_win_id = 0;
/*
* Allocate a window structure and link it in the window list when "hidden" is
* FALSE.
@@ -3695,6 +3697,7 @@ static win_T *win_alloc(win_T *after, int hidden)
win_T *new_wp = xcalloc(1, sizeof(win_T));
handle_register_window(new_wp);
win_alloc_lines(new_wp);
new_wp->w_id = ++last_win_id;
/* init w: variables */
new_wp->w_vars = dict_alloc();
@@ -5674,3 +5677,93 @@ static bool frame_check_width(frame_T *topfrp, int width)
}
return true;
}
int win_getid(typval_T *argvars)
{
if (argvars[0].v_type == VAR_UNKNOWN) {
return curwin->w_id;
}
int winnr = get_tv_number(&argvars[0]);
win_T *wp;
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;
}