To: vim_dev@googlegroups.com Subject: Patch 8.2.1081 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1081 Problem: Lua: cannot use table.insert() and table.remove(). Solution: Add the list functions. (Prabir Shrestha, closes #6353) Files: runtime/doc/if_lua.txt, src/if_lua.c, src/testdir/test_lua.vim *** ../vim-8.2.1080/runtime/doc/if_lua.txt 2020-06-27 12:32:54.311608957 +0200 --- runtime/doc/if_lua.txt 2020-06-28 22:39:05.571921785 +0200 *************** *** 227,234 **** 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". Methods ------- --- 227,243 ---- 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". Item can ! be added to the end of the list by "l[#l + 1] = newitem" o "l()" returns an iterator for "l". + o "table.insert(l, newitem)" inserts an item at the end of the list. + (only Lua 5.3 and later) + o "table.insert(l, position, newitem)" inserts an item at the + specified position. "position" is one-indexed. (only Lua 5.3 and + later) + o "table.remove(l, position)" removes an item at the specified + position. "position" is one-indexed. + Methods ------- *************** *** 246,253 **** :lua l[1] = nil -- remove first item :lua l:insert(true, 1) :lua print(l, #l, l[1], l[2]) :lua for item in l() do print(item) end - < ============================================================================== 4. Dict userdata *lua-dict* --- 255,265 ---- :lua l[1] = nil -- remove first item :lua l:insert(true, 1) :lua print(l, #l, l[1], l[2]) + :lua l[#l + 1] = 'value' + :lua table.insert(l, 100) + :lua table.insert(l, 2, 200) + :lua table.remove(l, 1) :lua for item in l() do print(item) end ============================================================================== 4. Dict userdata *lua-dict* *** ../vim-8.2.1080/src/if_lua.c 2020-06-27 12:32:54.311608957 +0200 --- src/if_lua.c 2020-06-28 13:23:10.624720022 +0200 *************** *** 913,931 **** if (l->lv_lock) luaL_error(L, "list is locked"); li = list_find(l, n); ! if (li == NULL) return 0; ! if (lua_isnil(L, 3)) // remove? { ! vimlist_remove(l, li, li); ! listitem_free(l, li); } else { ! typval_T v; ! luaV_checktypval(L, 3, &v, "setting list item"); ! clear_tv(&li->li_tv); ! copy_tv(&v, &li->li_tv); ! clear_tv(&v); } return 0; } --- 913,944 ---- if (l->lv_lock) luaL_error(L, "list is locked"); li = list_find(l, n); ! if (li == NULL) { ! if (!lua_isnil(L, 3)) ! { ! typval_T v; ! luaV_checktypval(L, 3, &v, "inserting list item"); ! if (list_insert_tv(l, &v, li) == FAIL) ! luaL_error(L, "failed to add item to list"); ! clear_tv(&v); ! } } else { ! if (lua_isnil(L, 3)) // remove? ! { ! vimlist_remove(l, li, li); ! listitem_free(l, li); ! } ! else ! { ! typval_T v; ! luaV_checktypval(L, 3, &v, "setting list item"); ! clear_tv(&li->li_tv); ! copy_tv(&v, &li->li_tv); ! clear_tv(&v); ! } } return 0; } *** ../vim-8.2.1080/src/testdir/test_lua.vim 2020-06-27 12:32:54.315608887 +0200 --- src/testdir/test_lua.vim 2020-06-28 22:40:07.187666548 +0200 *************** *** 353,358 **** --- 353,384 ---- call assert_fails('lua vim.list(true)', '[string "vim chunk"]:1: table expected, got boolean') endfunc + func Test_lua_list_table_insert_remove() + let luaver = split(split(luaeval('_VERSION'), ' ')[1], '\.') + let major = str2nr(luaver[0]) + let minor = str2nr(luaver[1]) + + if major < 5 || (major == 5 && minor < 3) + throw 'Skipped: Lua version < 5.3' + endif + + let l = [1, 2] + lua t = vim.eval('l') + lua table.insert(t, 10) + lua t[#t + 1] = 20 + lua table.insert(t, 2, 30) + call assert_equal(l, [1, 30, 2, 10, 20]) + lua table.remove(t, 2) + call assert_equal(l, [1, 2, 10, 20]) + lua t[3] = nil + call assert_equal(l, [1, 2, 20]) + lua removed_value = table.remove(t, 3) + call assert_equal(luaeval('removed_value'), 20) + lua t = nil + lua removed_value = nil + unlet l + endfunc + " Test l() i.e. iterator on list func Test_lua_list_iter() lua l = vim.list():add('foo'):add('bar') *** ../vim-8.2.1080/src/version.c 2020-06-28 18:43:36.296992324 +0200 --- src/version.c 2020-06-28 22:40:56.235462748 +0200 *************** *** 756,757 **** --- 756,759 ---- { /* Add new patch number below this line */ + /**/ + 1081, /**/ -- Every time I lose weight, it finds me again! /// 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 ///