diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer_defs.h | 5 | ||||
-rw-r--r-- | src/nvim/eval.c | 32 | ||||
-rw-r--r-- | src/nvim/testdir/Makefile | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_window_id.vim | 71 | ||||
-rw-r--r-- | src/nvim/version.c | 2 | ||||
-rw-r--r-- | src/nvim/window.c | 93 |
6 files changed, 200 insertions, 4 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index b515c4e1e4..46687f344c 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -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 */ diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a5333d74be..7839a7f645 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -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; diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile index 9a0bba83fe..4979aae57a 100644 --- a/src/nvim/testdir/Makefile +++ b/src/nvim/testdir/Makefile @@ -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 diff --git a/src/nvim/testdir/test_window_id.vim b/src/nvim/testdir/test_window_id.vim new file mode 100644 index 0000000000..b9e9f45c49 --- /dev/null +++ b/src/nvim/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/nvim/version.c b/src/nvim/version.c index 6dcc8f622f..3b98b53068 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -720,7 +720,7 @@ static int included_patches[] = { // 1560 NA // 1559, // 1558, - // 1557, + 1557, // 1556 NA // 1555 NA 1554, diff --git a/src/nvim/window.c b/src/nvim/window.c index e267d493bf..350b54d595 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -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; +} |