To: vim_dev@googlegroups.com Subject: Patch 8.2.3459 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.3459 Problem: Vim9: need more tests for empty string arguments. Solution: Add more tests. Also use empty argument with menu_info() to get the top-level menu names. (Yegappan Lakshmanan, closes #8925) Files: runtime/doc/eval.txt, src/menu.c, src/testdir/test_menu.vim, src/testdir/test_vim9_builtin.vim *** ../vim-8.2.3458/runtime/doc/eval.txt 2021-09-14 16:53:39.316540671 +0100 --- runtime/doc/eval.txt 2021-09-30 18:47:39.389418516 +0100 *************** *** 7864,7870 **** menu_info({name} [, {mode}]) *menu_info()* Return information about the specified menu {name} in mode {mode}. The menu name should be specified without the ! shortcut character ('&'). {mode} can be one of these strings: "n" Normal --- 7938,7945 ---- menu_info({name} [, {mode}]) *menu_info()* Return information about the specified menu {name} in mode {mode}. The menu name should be specified without the ! shortcut character ('&'). If {name} is "", then the top-level ! menu names are returned. {mode} can be one of these strings: "n" Normal *************** *** 7915,7920 **** --- 7990,8009 ---- Examples: > :echo menu_info('Edit.Cut') :echo menu_info('File.Save', 'n') + + " Display the entire menu hierarchy in a buffer + func ShowMenu(name, pfx) + let m = menu_info(a:name) + call append(line('$'), a:pfx .. m.display) + for child in m->get('submenus', []) + call ShowMenu(a:name .. '.' .. escape(child, '.'), + \ a:pfx .. ' ') + endfor + endfunc + new + for topmenu in menu_info('').submenus + call ShowMenu(topmenu, '') + endfor < Can also be used as a |method|: > GetMenuName()->menu_info('v') *** ../vim-8.2.3458/src/menu.c 2021-07-27 21:00:39.749712387 +0100 --- src/menu.c 2021-09-30 18:47:39.389418516 +0100 *************** *** 2830,2838 **** * Get the information about a menu item in mode 'which' */ static int ! menuitem_getinfo(vimmenu_T *menu, int modes, dict_T *dict) { int status; if (menu_is_tearoff(menu->dname)) // skip tearoff menu item return OK; --- 2830,2856 ---- * Get the information about a menu item in mode 'which' */ static int ! menuitem_getinfo(char_u *menu_name, vimmenu_T *menu, int modes, dict_T *dict) { int status; + list_T *l; + + if (*menu_name == NUL) + { + // Return all the top-level menus + vimmenu_T *topmenu; + + l = list_alloc(); + if (l == NULL) + return FAIL; + + dict_add_list(dict, "submenus", l); + // get all the children. Skip PopUp[nvoci]. + for (topmenu = menu; topmenu != NULL; topmenu = topmenu->next) + if (!menu_is_hidden(topmenu->dname)) + list_append_string(l, topmenu->dname, -1); + return OK; + } if (menu_is_tearoff(menu->dname)) // skip tearoff menu item return OK; *************** *** 2903,2911 **** // If there are submenus, add all the submenu display names if (status == OK && menu->children != NULL) { - list_T *l = list_alloc(); vimmenu_T *child; if (l == NULL) return FAIL; --- 2921,2929 ---- // If there are submenus, add all the submenu display names if (status == OK && menu->children != NULL) { vimmenu_T *child; + l = list_alloc(); if (l == NULL) return FAIL; *************** *** 2992,2998 **** return; if (menu->modes & modes) ! menuitem_getinfo(menu, modes, retdict); } #endif // FEAT_MENU --- 3010,3016 ---- return; if (menu->modes & modes) ! menuitem_getinfo(menu_name, menu, modes, retdict); } #endif // FEAT_MENU *** ../vim-8.2.3458/src/testdir/test_menu.vim 2020-12-18 18:49:52.345571854 +0000 --- src/testdir/test_menu.vim 2021-09-30 18:47:39.393418560 +0100 *************** *** 407,412 **** --- 407,415 ---- \ shortcut: '', modes: ' ', submenus: ['menu']}, \ menu_info(']Test')) unmenu ]Test + + " Test for getting all the top-level menu names + call assert_notequal(menu_info('').submenus, []) endfunc " Test for keyword in a menu with 'cpo' containing '<' *** ../vim-8.2.3458/src/testdir/test_vim9_builtin.vim 2021-09-26 19:03:59.662298673 +0100 --- src/testdir/test_vim9_builtin.vim 2021-09-30 18:47:39.393418560 +0100 *************** *** 201,206 **** --- 201,208 ---- CheckDefAndScriptFailure2(['appendbufline(1, [1], "x")'], 'E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2') CheckDefAndScriptFailure2(['appendbufline(1, 1, {"a": 10})'], 'E1013: Argument 3: type mismatch, expected string but got dict', 'E1224: String, Number or List required for argument 3') bnum->bufwinid()->win_gotoid() + appendbufline('', 0, 'numbers') + getline(1)->assert_equal('numbers') bwipe! enddef *************** *** 326,331 **** --- 328,334 ---- def Test_bufload() assert_fails('bufload([])', 'E1220:') + bufload('')->assert_equal(0) enddef def Test_bufloaded() *************** *** 452,457 **** --- 455,464 ---- else CheckDefAndScriptFailure2(['ch_getbufnr(1, "a")'], 'E1013: Argument 1: type mismatch, expected channel but got number', 'E1217: Channel or Job required for argument 1') CheckDefAndScriptFailure2(['ch_getbufnr(test_null_channel(), 1)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2') + # test empty string argument for ch_getbufnr() + var job: job = job_start(&shell) + job->ch_getbufnr('')->assert_equal(-1) + job_stop(job) endif enddef *************** *** 488,493 **** --- 495,501 ---- else assert_fails('ch_logfile(true)', 'E1174:') assert_fails('ch_logfile("foo", true)', 'E1174:') + ch_logfile('', '')->assert_equal(0) CheckDefAndScriptFailure2(['ch_logfile(1)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') CheckDefAndScriptFailure2(['ch_logfile("a", true)'], 'E1013: Argument 2: type mismatch, expected string but got bool', 'E1174: String required for argument 2') *************** *** 749,754 **** --- 757,767 ---- CheckDefAndScriptFailure2(['deletebufline([], 2)'], 'E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1') CheckDefAndScriptFailure2(['deletebufline("a", [])'], 'E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2') CheckDefAndScriptFailure2(['deletebufline("a", 2, 0z10)'], 'E1013: Argument 3: type mismatch, expected string but got blob', 'E1220: String or Number required for argument 3') + new + setline(1, ['one', 'two']) + deletebufline('', 1) + getline(1, '$')->assert_equal(['two']) + bwipe! enddef def Test_diff_filler() *************** *** 2705,2710 **** --- 2718,2724 ---- CheckDefAndScriptFailure2(['remote_expr("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2') CheckDefAndScriptFailure2(['remote_expr("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3') CheckDefAndScriptFailure2(['remote_expr("a", "b", "c", "d")'], 'E1013: Argument 4: type mismatch, expected number but got string', 'E1210: Number required for argument 4') + CheckDefExecAndScriptFailure(['remote_expr("", "")'], 'E241: Unable to send to ') enddef def Test_remote_foreground() *************** *** 2715,2720 **** --- 2729,2735 ---- CheckDefAndScriptFailure2(['remote_foreground(10)'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') assert_fails('remote_foreground("NonExistingServer")', 'E241:') + assert_fails('remote_foreground("")', 'E241:') enddef def Test_remote_peek() *************** *** 2739,2744 **** --- 2754,2760 ---- CheckDefAndScriptFailure2(['remote_send(1, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') CheckDefAndScriptFailure2(['remote_send("a", 2)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2') CheckDefAndScriptFailure2(['remote_send("a", "b", 3)'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3') + assert_fails('remote_send("", "")', 'E241:') enddef def Test_remote_startserver() *************** *** 2985,2990 **** --- 3001,3007 ---- CheckDefAndScriptFailure2(['server2client(10, "b")'], 'E1013: Argument 1: type mismatch, expected string but got number', 'E1174: String required for argument 1') CheckDefAndScriptFailure2(['server2client("a", 10)'], 'E1013: Argument 2: type mismatch, expected string but got number', 'E1174: String required for argument 2') CheckDefExecAndScriptFailure(['server2client("", "a")'], 'E573: Invalid server id used') + CheckDefExecAndScriptFailure(['server2client("", "")'], 'E573: Invalid server id used') enddef def Test_shellescape() *************** *** 3087,3092 **** --- 3104,3111 ---- CheckDefAndScriptFailure2(['setbufline(1, [1], "x")'], 'E1013: Argument 2: type mismatch, expected string but got list', 'E1220: String or Number required for argument 2') CheckDefAndScriptFailure2(['setbufline(1, 1, {"a": 10})'], 'E1013: Argument 3: type mismatch, expected string but got dict', 'E1224: String, Number or List required for argument 3') bnum->bufwinid()->win_gotoid() + setbufline('', 1, 'nombres') + getline(1)->assert_equal('nombres') bw! enddef *************** *** 3244,3249 **** --- 3263,3270 ---- CheckDefAndScriptFailure2(['sign_getplaced(["x"])'], 'E1013: Argument 1: type mismatch, expected string but got list', 'E1220: String or Number required for argument 1') CheckDefAndScriptFailure2(['sign_getplaced(1, ["a"])'], 'E1013: Argument 2: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 2') CheckDefAndScriptFailure2(['sign_getplaced("a", 1.1)'], 'E1013: Argument 2: type mismatch, expected dict but got float', 'E1206: Dictionary required for argument 2') + CheckDefExecAndScriptFailure(['sign_getplaced(bufnr(), {lnum: ""})'], 'E1030: Using a String as a Number:') + sign_getplaced('')->assert_equal([{signs: [], bufnr: bufnr()}]) enddef def Test_sign_jump() *************** *** 3258,3269 **** --- 3279,3292 ---- CheckDefAndScriptFailure2(['sign_place(1, "b", 3, "d")'], 'E1013: Argument 3: type mismatch, expected string but got number', 'E1174: String required for argument 3') CheckDefAndScriptFailure2(['sign_place(1, "b", "c", 1.1)'], 'E1013: Argument 4: type mismatch, expected string but got float', 'E1220: String or Number required for argument 4') CheckDefAndScriptFailure2(['sign_place(1, "b", "c", "d", [1])'], 'E1013: Argument 5: type mismatch, expected dict but got list', 'E1206: Dictionary required for argument 5') + CheckDefExecAndScriptFailure(['sign_place(0, "", "MySign", bufnr(), {lnum: ""})'], 'E1209: Invalid value for a line number: ""') assert_fails("sign_place(0, '', '', '')", 'E155:') enddef def Test_sign_placelist() CheckDefAndScriptFailure2(['sign_placelist("x")'], 'E1013: Argument 1: type mismatch, expected list but got string', 'E1211: List required for argument 1') CheckDefAndScriptFailure2(['sign_placelist({"a": 10})'], 'E1013: Argument 1: type mismatch, expected list but got dict', 'E1211: List required for argument 1') + CheckDefExecAndScriptFailure(['sign_placelist([{"name": "MySign", "buffer": bufnr(), "lnum": ""}])'], 'E1209: Invalid value for a line number: ""') enddef def Test_sign_undefine() *** ../vim-8.2.3458/src/version.c 2021-09-26 21:55:57.720529413 +0100 --- src/version.c 2021-09-30 18:49:42.606819721 +0100 *************** *** 759,760 **** --- 759,762 ---- { /* Add new patch number below this line */ + /**/ + 3459, /**/ -- From "know your smileys": y:-) Bad toupee /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///