diff options
author | Bram Moolenaar <Bram@vim.org> | 2016-03-13 18:07:30 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2016-03-13 18:07:30 +0100 |
commit | 86edef664efccbfe685906c854b9cdd04e56f2d5 (patch) | |
tree | 8c60cfa3d606624d81812b058124a4eac774fab8 /src | |
parent | a3442cb5056ca62fc71fa03f68a9395e4391caf4 (diff) |
patch 7.4.1557v7.4.1557
Problem: Windows cannot be identified.
Solution: Add a unique window number to each window and functions to use it.
Diffstat (limited to 'src')
-rw-r--r-- | src/eval.c | 48 | ||||
-rw-r--r-- | src/proto/eval.pro | 1 | ||||
-rw-r--r-- | src/proto/window.pro | 4 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/testdir/Make_all.mak | 1 | ||||
-rw-r--r-- | src/testdir/test_window_id.vim | 71 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 100 |
8 files changed, 227 insertions, 2 deletions
diff --git a/src/eval.c b/src/eval.c index 0b589fdc0f..5025a52c19 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 f5e0d19504..7035f26e24 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 613fe219bb..3c511e3c54 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 6bf21263ab..4aa7415f0f 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 5ad1718c6f..233ca12dfd 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 0000000000..b9e9f45c49 --- /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 9c15aafc81..bed7a46042 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 7dfbe5a991..b6111bd15c 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 |