changeset 18035:11dca9732a48 v8.1.2013

patch 8.1.2013: more functions can be used as methods Commit: https://github.com/vim/vim/commit/f92e58cadb03156879e9bdbf6341bf662d9c87cc Author: Bram Moolenaar <Bram@vim.org> Date: Sun Sep 8 21:51:41 2019 +0200 patch 8.1.2013: more functions can be used as methods Problem: More functions can be used as methods. Solution: Make various functions usable as a method.
author Bram Moolenaar <Bram@vim.org>
date Sun, 08 Sep 2019 22:00:04 +0200
parents 834b9558f93c
children 8b9e77aa11c2
files runtime/doc/eval.txt src/evalfunc.c src/testdir/test_cursor_func.vim src/testdir/test_execute_func.vim src/testdir/test_functions.vim src/testdir/test_listchars.vim src/testdir/test_timers.vim src/testdir/test_undo.vim src/testdir/test_window_cmd.vim src/testdir/test_window_id.vim src/version.c
diffstat 11 files changed, 146 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -9750,7 +9750,10 @@ timer_info([{id}])
 		    "callback"	    the callback
 		    "paused"	    1 if the timer is paused, 0 otherwise
 
-		{only available when compiled with the |+timers| feature}
+		Can also be used as a |method|: >
+			GetTimer()->timer_info()
+
+<		{only available when compiled with the |+timers| feature}
 
 timer_pause({timer}, {paused})				*timer_pause()*
 		Pause or unpause a timer.  A paused timer does not invoke its
@@ -9765,7 +9768,10 @@ timer_pause({timer}, {paused})				*timer
 		String, then the timer is paused, otherwise it is unpaused.
 		See |non-zero-arg|.
 
-		{only available when compiled with the |+timers| feature}
+		Can also be used as a |method|: >
+			GetTimer()->timer_pause(1)
+
+<		{only available when compiled with the |+timers| feature}
 
 						*timer_start()* *timer* *timers*
 timer_start({time}, {callback} [, {options}])
@@ -9798,7 +9804,10 @@ timer_start({time}, {callback} [, {optio
 <		This will invoke MyHandler() three times at 500 msec
 		intervals.
 
-		Not available in the |sandbox|.
+		Can also be used as a |method|: >
+			GetMsec()->timer_start(callback)
+
+<		Not available in the |sandbox|.
 		{only available when compiled with the |+timers| feature}
 
 timer_stop({timer})					*timer_stop()*
@@ -9806,7 +9815,10 @@ timer_stop({timer})					*timer_stop()*
 		{timer} is an ID returned by timer_start(), thus it must be a
 		Number.  If {timer} does not exist there is no error.
 
-		{only available when compiled with the |+timers| feature}
+		Can also be used as a |method|: >
+			GetTimer()->timer_stop()
+
+<		{only available when compiled with the |+timers| feature}
 
 timer_stopall()						*timer_stopall()*
 		Stop all timers.  The timer callbacks will no longer be
@@ -9820,11 +9832,17 @@ tolower({expr})						*tolower()*
 		characters turned into lowercase (just like applying |gu| to
 		the string).
 
+		Can also be used as a |method|: >
+			GetText()->tolower()
+
 toupper({expr})						*toupper()*
 		The result is a copy of the String given, with all lowercase
 		characters turned into uppercase (just like applying |gU| to
 		the string).
 
+		Can also be used as a |method|: >
+			GetText()->toupper()
+
 tr({src}, {fromstr}, {tostr})				*tr()*
 		The result is a copy of the {src} string with all characters
 		which appear in {fromstr} replaced by the character in that
@@ -9839,6 +9857,9 @@ tr({src}, {fromstr}, {tostr})				*tr()*
 			echo tr("<blob>", "<>", "{}")
 <		returns "{blob}"
 
+		Can also be used as a |method|: >
+			GetText()->tr(from, to)
+
 trim({text} [, {mask}])						*trim()*
 		Return {text} as a String where any character in {mask} is
 		removed from the beginning and  end of {text}.
@@ -9855,6 +9876,9 @@ trim({text} [, {mask}])						*trim()*
 			echo trim("rm<Xrm<>X>rrm", "rm<>")
 <		returns "Xrm<>X" (characters in the middle are not removed)
 
+		Can also be used as a |method|: >
+			GetText()->trim()
+
 trunc({expr})							*trunc()*
 		Return the largest integral value with magnitude less than or
 		equal to {expr} as a |Float| (truncate towards zero).
@@ -9915,6 +9939,9 @@ undofile({name})					*undofile()*
 		When compiled without the |+persistent_undo| option this always
 		returns an empty string.
 
+		Can also be used as a |method|: >
+			GetFilename()->undofile()
+
 undotree()						*undotree()*
 		Return the current state of the undo tree in a dictionary with
 		the following items:
@@ -10013,8 +10040,11 @@ virtcol({expr})						*virtcol()*
 		all lines: >
 		    echo max(map(range(1, line('$')), "virtcol([v:val, '$'])"))
 
-
-visualmode([expr])						*visualmode()*
+<		Can also be used as a |method|: >
+			GetPos()->virtcol()
+
+
+visualmode([{expr}])						*visualmode()*
 		The result is a String, which describes the last Visual mode
 		used in the current buffer.  Initially it returns an empty
 		string, but once Visual mode has been used, it returns "v",
@@ -10028,7 +10058,7 @@ visualmode([expr])						*visualmode()*
 		Visual mode that was used.
 		If Visual mode is active, use |mode()| to get the Visual mode
 		(e.g., in a |:vmap|).
-		If [expr] is supplied and it evaluates to a non-zero Number or
+		If {expr} is supplied and it evaluates to a non-zero Number or
 		a non-empty String, then the Visual mode will be cleared and
 		the old value is returned.  See |non-zero-arg|.
 
@@ -10057,10 +10087,17 @@ win_execute({id}, {command} [, {silent}]
 		Not all commands are allowed in popup windows.
 		When window {id} does not exist then no error is given.
 
+		Can also be used as a |method|, the base is used for the
+		command: >
+			GetCommand()->win_execute(winid)
+
 win_findbuf({bufnr})					*win_findbuf()*
 		Returns a list with |window-ID|s for windows that contain
 		buffer {bufnr}.  When there is none the list is empty.
 
+		Can also be used as a |method|: >
+			GetBufnr()->win_findbuf()
+
 win_getid([{win} [, {tab}]])				*win_getid()*
 		Get the |window-ID| for the specified window.
 		When {win} is missing use the current window.
@@ -10070,20 +10107,32 @@ win_getid([{win} [, {tab}]])				*win_get
 		number {tab}.  The first tab has number one.
 		Return zero if the window cannot be found.
 
+		Can also be used as a |method|: >
+			GetWinnr()->win_getid()
+
 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.
 
+		Can also be used as a |method|: >
+			GetWinid()->win_gotoid()
+
 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.
 
+		Can also be used as a |method|: >
+			GetWinid()->win_id2tabwin()
+
 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.
 
+		Can also be used as a |method|: >
+			GetWinid()->win_id2win()
+
 win_screenpos({nr})					*win_screenpos()*
 		Return the screen position of window {nr} as a list with two
 		numbers: [row, col].  The first window always has position
@@ -10092,6 +10141,9 @@ win_screenpos({nr})					*win_screenpos()
 		Return [0, 0] if the window cannot be found in the current
 		tabpage.
 
+		Can also be used as a |method|: >
+			GetWinid()->win_screenpos()
+<
 							*winbufnr()*
 winbufnr({nr})	The result is a Number, which is the number of the buffer
 		associated with window {nr}.  {nr} can be the window number or
@@ -10119,6 +10171,9 @@ winheight({nr})						*winheight()*
 		This excludes any window toolbar line.
 		Examples: >
   :echo "The current window has " . winheight(0) . " lines."
+
+<		Can also be used as a |method|: >
+			GetWinid()->winheight()
 <
 winlayout([{tabnr}])					*winlayout()*
 		The result is a nested List containing the layout of windows
@@ -10149,6 +10204,9 @@ winlayout([{tabnr}])					*winlayout()*
 			['col', [['leaf', 1002], ['row', ['leaf', 1003],
 					     ['leaf', 1001]]], ['leaf', 1000]]
 <
+		Can also be used as a |method|: >
+			GetTabnr()->winlayout()
+<
 							*winline()*
 winline()	The result is a Number, which is the screen line of the cursor
 		in the window.  This is counting screen lines from the top of
@@ -10182,6 +10240,9 @@ winnr([{arg}])	The result is a Number, w
 			let window_count = winnr('$')
 			let prev_window = winnr('#')
 			let wnum = winnr('3k')
+
+<		Can also be used as a |method|: >
+			GetWinval()->winnr()
 <
 							*winrestcmd()*
 winrestcmd()	Returns a sequence of |:resize| commands that should restore
@@ -10210,6 +10271,9 @@ winrestview({dict})
 		If you have changed the values the result is unpredictable.
 		If the window size changed the result won't be the same.
 
+		Can also be used as a |method|: >
+			GetView()->winrestview()
+<
 							*winsaveview()*
 winsaveview()	Returns a |Dictionary| that contains information to restore
 		the view of the current window.  Use |winrestview()| to
@@ -10247,6 +10311,9 @@ winwidth({nr})						*winwidth()*
 <		For getting the terminal or screen size, see the 'columns'
 		option.
 
+		Can also be used as a |method|: >
+			GetWinid()->winwidth()
+
 
 wordcount()						*wordcount()*
 		The result is a dictionary of byte/chars/word statistics for
@@ -10308,6 +10375,9 @@ writefile({object}, {fname} [, {flags}])
 			:let fl = readfile("foo", "b")
 			:call writefile(fl, "foocopy", "b")
 
+<		Can also be used as a |method|: >
+			GetText()->writefile("thefile")
+
 
 xor({expr}, {expr})					*xor()*
 		Bitwise XOR on the two arguments.  The arguments are converted
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -822,46 +822,46 @@ static funcentry_T global_functions[] =
 #endif
     {"test_settime",	1, 1, FEARG_1,	  f_test_settime},
 #ifdef FEAT_TIMERS
-    {"timer_info",	0, 1, 0,	  f_timer_info},
-    {"timer_pause",	2, 2, 0,	  f_timer_pause},
-    {"timer_start",	2, 3, 0,	  f_timer_start},
-    {"timer_stop",	1, 1, 0,	  f_timer_stop},
+    {"timer_info",	0, 1, FEARG_1,	  f_timer_info},
+    {"timer_pause",	2, 2, FEARG_1,	  f_timer_pause},
+    {"timer_start",	2, 3, FEARG_1,	  f_timer_start},
+    {"timer_stop",	1, 1, FEARG_1,	  f_timer_stop},
     {"timer_stopall",	0, 0, 0,	  f_timer_stopall},
 #endif
-    {"tolower",		1, 1, 0,	  f_tolower},
-    {"toupper",		1, 1, 0,	  f_toupper},
-    {"tr",		3, 3, 0,	  f_tr},
-    {"trim",		1, 2, 0,	  f_trim},
+    {"tolower",		1, 1, FEARG_1,	  f_tolower},
+    {"toupper",		1, 1, FEARG_1,	  f_toupper},
+    {"tr",		3, 3, FEARG_1,	  f_tr},
+    {"trim",		1, 2, FEARG_1,	  f_trim},
 #ifdef FEAT_FLOAT
     {"trunc",		1, 1, FEARG_1,	  f_trunc},
 #endif
     {"type",		1, 1, FEARG_1,	  f_type},
-    {"undofile",	1, 1, 0,	  f_undofile},
+    {"undofile",	1, 1, FEARG_1,	  f_undofile},
     {"undotree",	0, 0, 0,	  f_undotree},
     {"uniq",		1, 3, FEARG_1,	  f_uniq},
     {"values",		1, 1, FEARG_1,	  f_values},
-    {"virtcol",		1, 1, 0,	  f_virtcol},
+    {"virtcol",		1, 1, FEARG_1,	  f_virtcol},
     {"visualmode",	0, 1, 0,	  f_visualmode},
     {"wildmenumode",	0, 0, 0,	  f_wildmenumode},
-    {"win_execute",	2, 3, 0,	  f_win_execute},
-    {"win_findbuf",	1, 1, 0,	  f_win_findbuf},
-    {"win_getid",	0, 2, 0,	  f_win_getid},
-    {"win_gotoid",	1, 1, 0,	  f_win_gotoid},
-    {"win_id2tabwin",	1, 1, 0,	  f_win_id2tabwin},
-    {"win_id2win",	1, 1, 0,	  f_win_id2win},
-    {"win_screenpos",	1, 1, 0,	  f_win_screenpos},
+    {"win_execute",	2, 3, FEARG_2,	  f_win_execute},
+    {"win_findbuf",	1, 1, FEARG_1,	  f_win_findbuf},
+    {"win_getid",	0, 2, FEARG_1,	  f_win_getid},
+    {"win_gotoid",	1, 1, FEARG_1,	  f_win_gotoid},
+    {"win_id2tabwin",	1, 1, FEARG_1,	  f_win_id2tabwin},
+    {"win_id2win",	1, 1, FEARG_1,	  f_win_id2win},
+    {"win_screenpos",	1, 1, FEARG_1,	  f_win_screenpos},
     {"winbufnr",	1, 1, FEARG_1,	  f_winbufnr},
     {"wincol",		0, 0, 0,	  f_wincol},
-    {"winheight",	1, 1, 0,	  f_winheight},
-    {"winlayout",	0, 1, 0,	  f_winlayout},
+    {"winheight",	1, 1, FEARG_1,	  f_winheight},
+    {"winlayout",	0, 1, FEARG_1,	  f_winlayout},
     {"winline",		0, 0, 0,	  f_winline},
-    {"winnr",		0, 1, 0,	  f_winnr},
+    {"winnr",		0, 1, FEARG_1,	  f_winnr},
     {"winrestcmd",	0, 0, 0,	  f_winrestcmd},
-    {"winrestview",	1, 1, 0,	  f_winrestview},
+    {"winrestview",	1, 1, FEARG_1,	  f_winrestview},
     {"winsaveview",	0, 0, 0,	  f_winsaveview},
-    {"winwidth",	1, 1, 0,	  f_winwidth},
+    {"winwidth",	1, 1, FEARG_1,	  f_winwidth},
     {"wordcount",	0, 0, 0,	  f_wordcount},
-    {"writefile",	2, 3, 0,	  f_writefile},
+    {"writefile",	2, 3, FEARG_1,	  f_writefile},
     {"xor",		2, 2, FEARG_1,	  f_xor},
 };
 
--- a/src/testdir/test_cursor_func.vim
+++ b/src/testdir/test_cursor_func.vim
@@ -83,7 +83,7 @@ func Test_screenpos()
   call assert_equal({'row': winrow,
 	\ 'col': wincol + 0,
 	\ 'curscol': wincol + 7,
-	\ 'endcol': wincol + 7}, screenpos(winid, 1, 1))
+	\ 'endcol': wincol + 7}, winid->screenpos(1, 1))
   call assert_equal({'row': winrow,
 	\ 'col': wincol + 13,
 	\ 'curscol': wincol + 13,
--- a/src/testdir/test_execute_func.vim
+++ b/src/testdir/test_execute_func.vim
@@ -91,7 +91,7 @@ func Test_win_execute()
   if has('textprop')
     let popupwin = popup_create('the popup win', {'line': 2, 'col': 3})
     redraw
-    let line = win_execute(popupwin, 'echo getline(1)')
+    let line = 'echo getline(1)'->win_execute(popupwin)
     call assert_match('the popup win', line)
 
     call popup_close(popupwin)
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -266,7 +266,7 @@ endfunc
 func s:normalize_fname(fname)
   let ret = substitute(a:fname, '\', '/', 'g')
   let ret = substitute(ret, '//', '/', 'g')
-  return tolower(ret)
+  return ret->tolower()
 endfunc
 
 func Test_resolve_win32()
@@ -505,7 +505,7 @@ func Test_toupper()
           \ toupper(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'))
 
   " Test with a few lowercase diacritics.
-  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", toupper("aàáâãäåāăąǎǟǡả"))
+  call assert_equal("AÀÁÂÃÄÅĀĂĄǍǞǠẢ", "aàáâãäåāăąǎǟǡả"->toupper())
   call assert_equal("BḂḆ", toupper("bḃḇ"))
   call assert_equal("CÇĆĈĊČ", toupper("cçćĉċč"))
   call assert_equal("DĎĐḊḎḐ", toupper("dďđḋḏḑ"))
@@ -568,6 +568,11 @@ func Test_toupper()
   call toupper("123\xC0\x80\xC0")
 endfunc
 
+func Test_tr()
+  call assert_equal('foo', tr('bar', 'bar', 'foo'))
+  call assert_equal('zxy', 'cab'->tr('abc', 'xyz'))
+endfunc
+
 " Tests for the mode() function
 let current_modes = ''
 func Save_mode()
@@ -1203,7 +1208,7 @@ endfunc
 
 func Test_trim()
   call assert_equal("Testing", trim("  \t\r\r\x0BTesting  \t\n\r\n\t\x0B\x0B"))
-  call assert_equal("Testing", trim("  \t  \r\r\n\n\x0BTesting  \t\n\r\n\t\x0B\x0B"))
+  call assert_equal("Testing", "  \t  \r\r\n\n\x0BTesting  \t\n\r\n\t\x0B\x0B"->trim())
   call assert_equal("RESERVE", trim("xyz \twwRESERVEzyww \t\t", " wxyz\t"))
   call assert_equal("wRE    \tSERVEzyww", trim("wRE    \tSERVEzyww"))
   call assert_equal("abcd\t     xxxx   tail", trim(" \tabcd\t     xxxx   tail"))
@@ -1617,7 +1622,7 @@ func Test_bufadd_bufload()
   call assert_equal([''], getbufline(buf, 1, '$'))
 
   let curbuf = bufnr('')
-  call writefile(['some', 'text'], 'XotherName')
+  eval ['some', 'text']->writefile('XotherName')
   let buf = 'XotherName'->bufadd()
   call assert_notequal(0, buf)
   eval 'XotherName'->bufexists()->assert_equal(1)
--- a/src/testdir/test_listchars.vim
+++ b/src/testdir/test_listchars.vim
@@ -25,7 +25,7 @@ func Test_listchars()
   redraw!
   for i in range(1, 5)
     call cursor(i, 1)
-    call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+    call assert_equal([expected[i - 1]], ScreenLines(i, '$'->virtcol()))
   endfor
 
   set listchars-=trail:<
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -71,7 +71,7 @@ endfunc
 
 func Test_timer_info()
   let id = timer_start(1000, 'MyHandler')
-  let info = timer_info(id)
+  let info = id->timer_info()
   call assert_equal(id, info[0]['id'])
   call assert_equal(1000, info[0]['time'])
   call assert_true(info[0]['remaining'] > 500)
@@ -109,7 +109,7 @@ func Test_timer_paused()
   let info = timer_info(id)
   call assert_equal(0, info[0]['paused'])
 
-  call timer_pause(id, 1)
+  eval id->timer_pause(1)
   let info = timer_info(id)
   call assert_equal(1, info[0]['paused'])
   sleep 100m
@@ -149,7 +149,7 @@ func Test_timer_delete_myself()
 endfunc
 
 func StopTimer1(timer)
-  let g:timer2 = timer_start(10, 'StopTimer2')
+  let g:timer2 = 10->timer_start('StopTimer2')
   " avoid maxfuncdepth error
   call timer_pause(g:timer1, 1)
   sleep 20m
@@ -262,7 +262,7 @@ func Test_timer_peek_and_get_char()
   let intr = timer_start(100, 'Interrupt')
   let c = getchar()
   call assert_equal(char2nr('a'), c)
-  call timer_stop(intr)
+  eval intr->timer_stop()
 endfunc
 
 func Test_timer_getchar_zero()
--- a/src/testdir/test_undo.vim
+++ b/src/testdir/test_undo.vim
@@ -456,7 +456,7 @@ funct Test_undofile()
   call delete('Xundodir', 'd')
 
   " Test undofile() with 'undodir' set to a non-existing directory.
-  call assert_equal('', undofile('Xundofoo'))
+  call assert_equal('', 'Xundofoo'->undofile())
 
   if isdirectory('/tmp')
     set undodir=/tmp
--- a/src/testdir/test_window_cmd.vim
+++ b/src/testdir/test_window_cmd.vim
@@ -72,7 +72,7 @@ endfunc
 func Test_window_quit()
   e Xa
   split Xb
-  call assert_equal(2, winnr('$'))
+  call assert_equal(2, '$'->winnr())
   call assert_equal('Xb', bufname(winbufnr(1)))
   call assert_equal('Xa', bufname(winbufnr(2)))
 
@@ -88,7 +88,7 @@ func Test_window_horizontal_split()
   3wincmd s
   call assert_equal(2, winnr('$'))
   call assert_equal(3, winheight(0))
-  call assert_equal(winwidth(1), winwidth(2))
+  call assert_equal(winwidth(1), 2->winwidth())
 
   call assert_fails('botright topleft wincmd s', 'E442:')
   bw
@@ -300,7 +300,7 @@ func Test_window_height()
 
   wincmd +
   call assert_equal(wh1, winheight(1))
-  call assert_equal(wh2, winheight(2))
+  call assert_equal(wh2, 2->winheight())
 
   2wincmd _
   call assert_equal(2, winheight(1))
@@ -845,4 +845,16 @@ func Test_winnr()
   only | tabonly
 endfunc
 
+func Test_winrestview()
+  split runtest.vim
+  normal 50%
+  let view = winsaveview()
+  close
+  split runtest.vim
+  eval view->winrestview()
+  call assert_equal(view, winsaveview())
+
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/testdir/test_window_id.vim
+++ b/src/testdir/test_window_id.vim
@@ -67,7 +67,7 @@ func Test_win_getid()
 
   call win_gotoid(id2)
   call assert_equal("two", expand("%"))
-  call win_gotoid(id4)
+  eval id4->win_gotoid()
   call assert_equal("four", expand("%"))
   call win_gotoid(id1)
   call assert_equal("one", expand("%"))
@@ -75,17 +75,17 @@ func Test_win_getid()
   call assert_equal("five", expand("%"))
 
   call assert_equal(0, win_id2win(9999))
-  call assert_equal(nr5, win_id2win(id5))
+  call assert_equal(nr5, id5->win_id2win())
   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([1, nr2], id2->win_id2tabwin())
   call assert_equal([2, nr4], win_id2tabwin(id4))
 
   call assert_equal([], win_findbuf(9999))
-  call assert_equal([id2], win_findbuf(bufnr2))
+  call assert_equal([id2], bufnr2->win_findbuf())
   call win_gotoid(id5)
   split
   call assert_equal(sort([id5, win_getid()]), sort(win_findbuf(bufnr5)))
@@ -98,7 +98,7 @@ func Test_win_getid_curtab()
   tabfirst
   copen
   only
-  call assert_equal(win_getid(1), win_getid(1, 1))
+  call assert_equal(win_getid(1), 1->win_getid( 1))
   tabclose!
 endfunc
 
@@ -120,4 +120,11 @@ func Test_winlayout()
   call assert_equal(['col', [['leaf', w3], ['row', [['leaf', w4], ['leaf', w2]]], ['leaf', w1]]], winlayout())
 
   only!
+
+  let w1 = win_getid()
+  call assert_equal(['leaf', w1], winlayout(1))
+  tabnew
+  let w2 = win_getid()
+  call assert_equal(['leaf', w2], 2->winlayout())
+  tabclose
 endfunc
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2013,
+/**/
     2012,
 /**/
     2011,