To: vim_dev@googlegroups.com Subject: Patch 7.4.1557 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.1557 Problem: Windows cannot be identified. Solution: Add a unique window number to each window and functions to use it. Files: src/structs.h, src/window.c, src/eval.c, src/proto/eval.pro, src/proto/window.pro, src/testdir/test_window_id.vim, src/testdir/Make_all.mak, runtime/doc/eval.txt *** ../vim-7.4.1556/src/structs.h 2016-03-11 22:52:00.714438325 +0100 --- src/structs.h 2016-03-13 16:09:29.933445965 +0100 *************** *** 2273,2278 **** --- 2273,2280 ---- */ 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!) */ *** ../vim-7.4.1556/src/window.c 2016-03-03 12:22:48.570553923 +0100 --- src/window.c 2016-03-13 17:59:57.093134447 +0100 *************** *** 4541,4546 **** --- 4541,4548 ---- } #endif + static int last_win_id = 0; + /* * Allocate a window structure and link it in the window list when "hidden" is * FALSE. *************** *** 4563,4568 **** --- 4565,4572 ---- return NULL; } + new_wp->w_id = ++last_win_id; + #ifdef FEAT_EVAL /* init w: variables */ new_wp->w_vars = dict_alloc(); *************** *** 7198,7200 **** --- 7202,7300 ---- } #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 *** ../vim-7.4.1556/src/eval.c 2016-03-12 22:11:34.251300154 +0100 --- src/eval.c 2016-03-13 17:03:13.060158944 +0100 *************** *** 434,440 **** 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); --- 434,439 ---- *************** *** 808,813 **** --- 807,816 ---- 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,6475 **** * Append "n" to list "l". * Returns FAIL when out of memory. */ ! static int list_append_number(list_T *l, varnumber_T n) { listitem_T *li; --- 6472,6478 ---- * Append "n" to list "l". * Returns FAIL when out of memory. */ ! int list_append_number(list_T *l, varnumber_T n) { listitem_T *li; *************** *** 8385,8390 **** --- 8388,8397 ---- {"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,12667 **** --- 12669,12711 ---- } /* + * "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 *** ../vim-7.4.1556/src/proto/eval.pro 2016-03-12 13:43:28.860478230 +0100 --- src/proto/eval.pro 2016-03-13 17:02:45.060447603 +0100 *************** *** 59,64 **** --- 59,65 ---- 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); *** ../vim-7.4.1556/src/proto/window.pro 2016-01-19 13:21:55.849334247 +0100 --- src/proto/window.pro 2016-03-13 17:02:48.084416429 +0100 *************** *** 83,86 **** --- 83,90 ---- 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 : */ *** ../vim-7.4.1556/src/testdir/test_window_id.vim 2016-03-13 18:04:27.774356445 +0100 --- src/testdir/test_window_id.vim 2016-03-13 17:58:14.842185314 +0100 *************** *** 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 *** ../vim-7.4.1556/src/testdir/Make_all.mak 2016-03-05 21:21:09.087720248 +0100 --- src/testdir/Make_all.mak 2016-03-13 17:16:04.028205465 +0100 *************** *** 186,191 **** --- 186,192 ---- test_viminfo.res \ test_viml.res \ test_visual.res \ + test_window_id.res \ test_alot.res *** ../vim-7.4.1556/runtime/doc/eval.txt 2016-03-12 19:03:28.217328858 +0100 --- runtime/doc/eval.txt 2016-03-13 17:13:49.389595126 +0100 *************** *** 2133,2138 **** --- 2149,2158 ---- 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} *************** *** 7072,7077 **** --- 7176,7204 ---- (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 *** ../vim-7.4.1556/src/version.c 2016-03-13 14:34:07.628766258 +0100 --- src/version.c 2016-03-13 18:03:53.282709302 +0100 *************** *** 745,746 **** --- 745,748 ---- { /* Add new patch number below this line */ + /**/ + 1557, /**/ -- Have you heard about the new Beowulf cluster? It's so fast, it executes an infinite loop in 6 seconds. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///