# HG changeset patch # User Bram Moolenaar # Date 1593254704 -7200 # Node ID 08e284594211a46fa02a06d911690bb5affbf373 # Parent 857b879cfc59363030769c4a2c250b3510620efa patch 8.2.1066: Lua arrays are zero based Commit: https://github.com/vim/vim/commit/bd84617d1a6766efd59c94aabebb044bef805b99 Author: Bram Moolenaar Date: Sat Jun 27 12:32:57 2020 +0200 patch 8.2.1066: Lua arrays are zero based Problem: Lua arrays are zero based. Solution: Make Lua arrays one based. (Prabir Shrestha, closes https://github.com/vim/vim/issues/6347) Note: this is not backwards compatible. diff --git a/runtime/doc/if_lua.txt b/runtime/doc/if_lua.txt --- a/runtime/doc/if_lua.txt +++ b/runtime/doc/if_lua.txt @@ -217,11 +217,15 @@ Vim's syntax for lists. Since lists are Lua are reflected in Vim and vice-versa. A list "l" has the following properties and methods: +NOTE: In patch 8.2.1066 array indexes were changed from zero-based to +one-based. You can check with: > + if has("patch-8.2.1066") + Properties ---------- o "#l" is the number of items in list "l", equivalent to "len(l)" in Vim. - o "l[k]" returns the k-th item in "l"; "l" is zero-indexed, as in Vim. + o "l[k]" returns the k-th item in "l"; "l" is one-indexed, as in Lua. To modify the k-th item, simply do "l[k] = newitem"; in particular, "l[k] = nil" removes the k-th item from "l". o "l()" returns an iterator for "l". @@ -237,11 +241,11 @@ Examples: :let l = [1, 'item'] :lua l = vim.eval('l') -- same 'l' :lua l:add(vim.list()) - :lua l[0] = math.pi + :lua l[1] = math.pi :echo l[0] " 3.141593 - :lua l[0] = nil -- remove first item + :lua l[1] = nil -- remove first item :lua l:insert(true, 1) - :lua print(l, #l, l[0], l[1], l[-1]) + :lua print(l, #l, l[1], l[2]) :lua for item in l() do print(item) end < diff --git a/src/if_lua.c b/src/if_lua.c --- a/src/if_lua.c +++ b/src/if_lua.c @@ -871,7 +871,13 @@ luaV_list_index(lua_State *L) list_T *l = luaV_unbox(L, luaV_List, 1); if (lua_isnumber(L, 2)) // list item? { - listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2)); + long n = (long) luaL_checkinteger(L, 2); + listitem_T *li; + + // Lua array index starts with 1 while Vim uses 0, subtract 1 to + // normalize. + n -= 1; + li = list_find(l, n); if (li == NULL) lua_pushnil(L); else @@ -900,6 +906,10 @@ luaV_list_newindex(lua_State *L) list_T *l = luaV_unbox(L, luaV_List, 1); long n = (long) luaL_checkinteger(L, 2); listitem_T *li; + + // Lua array index starts with 1 while Vim uses 0, subtract 1 to normalize. + n -= 1; + if (l->lv_lock) luaL_error(L, "list is locked"); li = list_find(l, n); diff --git a/src/testdir/test_lua.vim b/src/testdir/test_lua.vim --- a/src/testdir/test_lua.vim +++ b/src/testdir/test_lua.vim @@ -327,8 +327,8 @@ func Test_lua_list() call assert_equal(7, luaeval('#l')) call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)')) - lua l[0] = 124 - lua l[5] = nil + lua l[1] = 124 + lua l[6] = nil lua l:insert('first') lua l:insert('xx', 3) call assert_equal(['first', 124, 'abc', 'xx', v:true, v:false, v:null, {'a': 1, 'b': 2, 'c': 3}], l) @@ -367,22 +367,22 @@ func Test_lua_recursive_list() lua l = vim.list():add(1):add(2) lua l = l:add(l) - call assert_equal(1, luaeval('l[0]')) - call assert_equal(2, luaeval('l[1]')) + call assert_equal(1, luaeval('l[1]')) + call assert_equal(2, luaeval('l[2]')) - call assert_equal(1, luaeval('l[2][0]')) - call assert_equal(2, luaeval('l[2][1]')) + call assert_equal(1, luaeval('l[3][1]')) + call assert_equal(2, luaeval('l[3][2]')) - call assert_equal(1, luaeval('l[2][2][0]')) - call assert_equal(2, luaeval('l[2][2][1]')) + call assert_equal(1, luaeval('l[3][3][1]')) + call assert_equal(2, luaeval('l[3][3][2]')) call assert_equal('[1, 2, [...]]', string(luaeval('l'))) call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)')) - call assert_equal(luaeval('tostring(l)'), luaeval('tostring(l[2])')) + call assert_equal(luaeval('tostring(l)'), luaeval('tostring(l[3])')) - call assert_equal(luaeval('l'), luaeval('l[2]')) - call assert_equal(luaeval('l'), luaeval('l[2][2]')) + call assert_equal(luaeval('l'), luaeval('l[3]')) + call assert_equal(luaeval('l'), luaeval('l[3][3]')) lua l = nil endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -755,6 +755,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1066, +/**/ 1065, /**/ 1064,