To: vim_dev@googlegroups.com Subject: Patch 8.2.4565 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4565 Problem: No command line completion for :breakadd and :breakdel. Solution: Add completion for :breakadd and :breakdel. (Yegappan Lakshmanan, closes #9950) Files: runtime/doc/builtin.txt, src/cmdexpand.c, src/spellsuggest.c, src/usercmd.c, src/vim.h, src/testdir/test_cmdline.vim, src/testdir/test_writefile.vim *** ../vim-8.2.4564/runtime/doc/builtin.txt 2022-02-23 13:16:55.757541153 +0000 --- runtime/doc/builtin.txt 2022-03-14 19:16:37.719994346 +0000 *************** *** 3220,3226 **** arglist file names in argument list augroup autocmd groups buffer buffer names ! behave :behave suboptions color color schemes command Ex command cmdline |cmdline-completion| result --- 3230,3237 ---- arglist file names in argument list augroup autocmd groups buffer buffer names ! behave |:behave| suboptions ! breakpoint |:breakadd| and |:breakdel| suboptions color color schemes command Ex command cmdline |cmdline-completion| result *************** *** 3237,3243 **** function function name help help subjects highlight highlight groups ! history :history suboptions locale locale names (as output of locale -a) mapclear buffer argument mapping mapping name --- 3248,3254 ---- function function name help help subjects highlight highlight groups ! history |:history| suboptions locale locale names (as output of locale -a) mapclear buffer argument mapping mapping name *** ../vim-8.2.4564/src/cmdexpand.c 2022-02-28 21:02:16.271053073 +0000 --- src/cmdexpand.c 2022-03-14 19:16:37.719994346 +0000 *************** *** 1602,1607 **** --- 1602,1672 ---- } #endif + #ifdef FEAT_EVAL + static enum + { + EXP_BREAKPT_ADD, // expand ":breakadd" sub-commands + EXP_BREAKPT_DEL // expand ":breakdel" sub-commands + } breakpt_expand_what; + + /* + * Set the completion context for the :breakadd command. Always returns NULL. + */ + static char_u * + set_context_in_breakadd_cmd(expand_T *xp, char_u *arg, cmdidx_T cmdidx) + { + char_u *p; + char_u *subcmd_start; + + xp->xp_context = EXPAND_BREAKPOINT; + xp->xp_pattern = arg; + + if (cmdidx == CMD_breakadd) + breakpt_expand_what = EXP_BREAKPT_ADD; + else + breakpt_expand_what = EXP_BREAKPT_DEL; + + p = skipwhite(arg); + if (*p == NUL) + return NULL; + subcmd_start = p; + + if (STRNCMP("file ", p, 5) == 0 || + STRNCMP("func ", p, 5) == 0) + { + // :breakadd file [lnum] + // :breakadd func [lnum] + p += 4; + p = skipwhite(p); + + // skip line number (if specified) + if (VIM_ISDIGIT(*p)) + { + p = skipdigits(p); + if (*p != ' ') + { + xp->xp_context = EXPAND_NOTHING; + return NULL; + } + p = skipwhite(p); + } + if (STRNCMP("file", subcmd_start, 4) == 0) + xp->xp_context = EXPAND_FILES; + else + xp->xp_context = EXPAND_USER_FUNC; + xp->xp_pattern = p; + } + else if (STRNCMP("expr ", p, 5) == 0) + { + // :breakadd expr + xp->xp_context = EXPAND_EXPRESSION; + xp->xp_pattern = skipwhite(p + 5); + } + + return NULL; + } + #endif + /* * Set the completion context in 'xp' for command 'cmd' with index 'cmdidx'. * The argument to the command is 'arg' and the argument flags is 'argt'. *************** *** 1958,1963 **** --- 2023,2034 ---- xp->xp_pattern = arg; break; + #ifdef FEAT_EVAL + case CMD_breakadd: + case CMD_breakdel: + return set_context_in_breakadd_cmd(xp, arg, cmdidx); + #endif + default: break; } *************** *** 2348,2353 **** --- 2419,2449 ---- return NULL; } + # ifdef FEAT_EVAL + /* + * Function given to ExpandGeneric() to obtain the possible arguments of the + * ":breakadd {expr, file, func, here}" command. + * ":breakdel {func, file, here}" command. + */ + static char_u * + get_breakadd_arg(expand_T *xp UNUSED, int idx) + { + char *opts[] = {"expr", "file", "func", "here"}; + + if (idx >=0 && idx <= 3) + { + if (breakpt_expand_what == EXP_BREAKPT_ADD) + return (char_u *)opts[idx]; + else + { + if (idx <= 2) + return (char_u *)opts[idx + 1]; + } + } + return NULL; + } + #endif + /* * Function given to ExpandGeneric() to obtain the possible arguments of the * ":messages {clear}" command. *************** *** 2397,2438 **** {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE}, {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE}, {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE}, ! # ifdef FEAT_EVAL {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE}, {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE}, {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE}, {EXPAND_DISASSEMBLE, get_disassemble_argument, FALSE, TRUE}, {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE}, ! # endif ! # ifdef FEAT_MENU {EXPAND_MENUS, get_menu_name, FALSE, TRUE}, {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE}, ! # endif ! # ifdef FEAT_SYN_HL {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE}, ! # endif ! # ifdef FEAT_PROFILE {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE}, ! # endif {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE}, {EXPAND_EVENTS, get_event_name, TRUE, FALSE}, {EXPAND_AUGROUP, get_augroup_name, TRUE, FALSE}, ! # ifdef FEAT_CSCOPE {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE}, ! # endif ! # ifdef FEAT_SIGNS {EXPAND_SIGN, get_sign_name, TRUE, TRUE}, ! # endif ! # ifdef FEAT_PROFILE {EXPAND_PROFILE, get_profile_name, TRUE, TRUE}, ! # endif ! # if defined(HAVE_LOCALE_H) || defined(X_LOCALE) {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE}, {EXPAND_LOCALES, get_locales, TRUE, FALSE}, ! # endif {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE}, {EXPAND_USER, get_users, TRUE, FALSE}, {EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE}, }; int i; int ret = FAIL; --- 2493,2537 ---- {EXPAND_USER_CMD_FLAGS, get_user_cmd_flags, FALSE, TRUE}, {EXPAND_USER_NARGS, get_user_cmd_nargs, FALSE, TRUE}, {EXPAND_USER_COMPLETE, get_user_cmd_complete, FALSE, TRUE}, ! #ifdef FEAT_EVAL {EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE}, {EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE}, {EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE}, {EXPAND_DISASSEMBLE, get_disassemble_argument, FALSE, TRUE}, {EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE}, ! #endif ! #ifdef FEAT_MENU {EXPAND_MENUS, get_menu_name, FALSE, TRUE}, {EXPAND_MENUNAMES, get_menu_names, FALSE, TRUE}, ! #endif ! #ifdef FEAT_SYN_HL {EXPAND_SYNTAX, get_syntax_name, TRUE, TRUE}, ! #endif ! #ifdef FEAT_PROFILE {EXPAND_SYNTIME, get_syntime_arg, TRUE, TRUE}, ! #endif {EXPAND_HIGHLIGHT, get_highlight_name, TRUE, TRUE}, {EXPAND_EVENTS, get_event_name, TRUE, FALSE}, {EXPAND_AUGROUP, get_augroup_name, TRUE, FALSE}, ! #ifdef FEAT_CSCOPE {EXPAND_CSCOPE, get_cscope_name, TRUE, TRUE}, ! #endif ! #ifdef FEAT_SIGNS {EXPAND_SIGN, get_sign_name, TRUE, TRUE}, ! #endif ! #ifdef FEAT_PROFILE {EXPAND_PROFILE, get_profile_name, TRUE, TRUE}, ! #endif ! #if defined(HAVE_LOCALE_H) || defined(X_LOCALE) {EXPAND_LANGUAGE, get_lang_arg, TRUE, FALSE}, {EXPAND_LOCALES, get_locales, TRUE, FALSE}, ! #endif {EXPAND_ENV_VARS, get_env_name, TRUE, TRUE}, {EXPAND_USER, get_users, TRUE, FALSE}, {EXPAND_ARGLIST, get_arglist_name, TRUE, FALSE}, + #ifdef FEAT_EVAL + {EXPAND_BREAKPOINT, get_breakadd_arg, TRUE, TRUE}, + #endif }; int i; int ret = FAIL; *** ../vim-8.2.4564/src/spellsuggest.c 2022-03-13 20:12:21.322709463 +0000 --- src/spellsuggest.c 2022-03-14 19:16:37.719994346 +0000 *************** *** 508,514 **** end_visual_mode(); // make sure we don't include the NUL at the end of the line line = ml_get_curline(); ! if (badlen > STRLEN(line) - curwin->w_cursor.col) badlen = STRLEN(line) - curwin->w_cursor.col; } // Find the start of the badly spelled word. --- 508,514 ---- end_visual_mode(); // make sure we don't include the NUL at the end of the line line = ml_get_curline(); ! if (badlen > (int)STRLEN(line) - (int)curwin->w_cursor.col) badlen = STRLEN(line) - curwin->w_cursor.col; } // Find the start of the badly spelled word. *** ../vim-8.2.4564/src/usercmd.c 2022-02-20 20:48:53.226071796 +0000 --- src/usercmd.c 2022-03-14 19:16:37.723994349 +0000 *************** *** 90,95 **** --- 90,98 ---- {EXPAND_TAGS_LISTFILES, "tag_listfiles"}, {EXPAND_USER, "user"}, {EXPAND_USER_VARS, "var"}, + #if defined(FEAT_EVAL) + {EXPAND_BREAKPOINT, "breakpoint"}, + #endif {0, NULL} }; *** ../vim-8.2.4564/src/vim.h 2022-02-26 10:31:24.699882028 +0000 --- src/vim.h 2022-03-14 19:16:37.723994349 +0000 *************** *** 801,806 **** --- 801,807 ---- #define EXPAND_ARGLIST 48 #define EXPAND_DIFF_BUFFERS 49 #define EXPAND_DISASSEMBLE 50 + #define EXPAND_BREAKPOINT 51 // Values for exmode_active (0 is no exmode) #define EXMODE_NORMAL 1 *** ../vim-8.2.4564/src/testdir/test_cmdline.vim 2022-02-28 13:28:34.544563774 +0000 --- src/testdir/test_cmdline.vim 2022-03-14 19:16:37.719994346 +0000 *************** *** 3007,3010 **** --- 3007,3164 ---- set wildoptions& endfunc + " Test for :breakadd argument completion + func Test_cmdline_complete_breakadd() + call feedkeys(":breakadd \\\"\", 'tx') + call assert_equal("\"breakadd expr file func here", @:) + call feedkeys(":breakadd \\\"\", 'tx') + call assert_equal("\"breakadd expr", @:) + call feedkeys(":breakadd \\\"\", 'tx') + call assert_equal("\"breakadd expr", @:) + call feedkeys(":breakadd he\\\"\", 'tx') + call assert_equal("\"breakadd here", @:) + call feedkeys(":breakadd he\\\"\", 'tx') + call assert_equal("\"breakadd here", @:) + call feedkeys(":breakadd abc\\\"\", 'tx') + call assert_equal("\"breakadd abc", @:) + call assert_equal(['expr', 'file', 'func', 'here'], getcompletion('', 'breakpoint')) + let l = getcompletion('not', 'breakpoint') + call assert_equal([], l) + + " Test for :breakadd file [lnum] + call writefile([], 'Xscript') + call feedkeys(":breakadd file Xsc\\\"\", 'tx') + call assert_equal("\"breakadd file Xscript", @:) + call feedkeys(":breakadd file Xsc\\\"\", 'tx') + call assert_equal("\"breakadd file Xscript", @:) + call feedkeys(":breakadd file 20 Xsc\\\"\", 'tx') + call assert_equal("\"breakadd file 20 Xscript", @:) + call feedkeys(":breakadd file 20 Xsc\\\"\", 'tx') + call assert_equal("\"breakadd file 20 Xscript", @:) + call feedkeys(":breakadd file 20x Xsc\\\"\", 'tx') + call assert_equal("\"breakadd file 20x Xsc\t", @:) + call feedkeys(":breakadd file 20\\\"\", 'tx') + call assert_equal("\"breakadd file 20\t", @:) + call feedkeys(":breakadd file 20x\\\"\", 'tx') + call assert_equal("\"breakadd file 20x\t", @:) + call feedkeys(":breakadd file Xscript \\\"\", 'tx') + call assert_equal("\"breakadd file Xscript ", @:) + call feedkeys(":breakadd file X1B2C3\\\"\", 'tx') + call assert_equal("\"breakadd file X1B2C3", @:) + call delete('Xscript') + + " Test for :breakadd func [lnum] + func Xbreak_func() + endfunc + call feedkeys(":breakadd func Xbr\\\"\", 'tx') + call assert_equal("\"breakadd func Xbreak_func", @:) + call feedkeys(":breakadd func Xbr\\\"\", 'tx') + call assert_equal("\"breakadd func Xbreak_func", @:) + call feedkeys(":breakadd func 20 Xbr\\\"\", 'tx') + call assert_equal("\"breakadd func 20 Xbreak_func", @:) + call feedkeys(":breakadd func 20 Xbr\\\"\", 'tx') + call assert_equal("\"breakadd func 20 Xbreak_func", @:) + call feedkeys(":breakadd func 20x Xbr\\\"\", 'tx') + call assert_equal("\"breakadd func 20x Xbr\t", @:) + call feedkeys(":breakadd func 20\\\"\", 'tx') + call assert_equal("\"breakadd func 20\t", @:) + call feedkeys(":breakadd func 20x\\\"\", 'tx') + call assert_equal("\"breakadd func 20x\t", @:) + call feedkeys(":breakadd func Xbreak_func \\\"\", 'tx') + call assert_equal("\"breakadd func Xbreak_func ", @:) + call feedkeys(":breakadd func X1B2C3\\\"\", 'tx') + call assert_equal("\"breakadd func X1B2C3", @:) + delfunc Xbreak_func + + " Test for :breakadd expr + let g:Xtest_var = 10 + call feedkeys(":breakadd expr Xtest\\\"\", 'tx') + call assert_equal("\"breakadd expr Xtest_var", @:) + call feedkeys(":breakadd expr Xtest\\\"\", 'tx') + call assert_equal("\"breakadd expr Xtest_var", @:) + call feedkeys(":breakadd expr Xtest_var \\\"\", 'tx') + call assert_equal("\"breakadd expr Xtest_var ", @:) + call feedkeys(":breakadd expr X1B2C3\\\"\", 'tx') + call assert_equal("\"breakadd expr X1B2C3", @:) + unlet g:Xtest_var + + " Test for :breakadd here + call feedkeys(":breakadd here Xtest\\\"\", 'tx') + call assert_equal("\"breakadd here Xtest", @:) + call feedkeys(":breakadd here Xtest\\\"\", 'tx') + call assert_equal("\"breakadd here Xtest", @:) + call feedkeys(":breakadd here \\\"\", 'tx') + call assert_equal("\"breakadd here ", @:) + endfunc + + " Test for :breakdel argument completion + func Test_cmdline_complete_breakdel() + call feedkeys(":breakdel \\\"\", 'tx') + call assert_equal("\"breakdel file func here", @:) + call feedkeys(":breakdel \\\"\", 'tx') + call assert_equal("\"breakdel file", @:) + call feedkeys(":breakdel \\\"\", 'tx') + call assert_equal("\"breakdel file", @:) + call feedkeys(":breakdel he\\\"\", 'tx') + call assert_equal("\"breakdel here", @:) + call feedkeys(":breakdel he\\\"\", 'tx') + call assert_equal("\"breakdel here", @:) + call feedkeys(":breakdel abc\\\"\", 'tx') + call assert_equal("\"breakdel abc", @:) + + " Test for :breakdel file [lnum] + call writefile([], 'Xscript') + call feedkeys(":breakdel file Xsc\\\"\", 'tx') + call assert_equal("\"breakdel file Xscript", @:) + call feedkeys(":breakdel file Xsc\\\"\", 'tx') + call assert_equal("\"breakdel file Xscript", @:) + call feedkeys(":breakdel file 20 Xsc\\\"\", 'tx') + call assert_equal("\"breakdel file 20 Xscript", @:) + call feedkeys(":breakdel file 20 Xsc\\\"\", 'tx') + call assert_equal("\"breakdel file 20 Xscript", @:) + call feedkeys(":breakdel file 20x Xsc\\\"\", 'tx') + call assert_equal("\"breakdel file 20x Xsc\t", @:) + call feedkeys(":breakdel file 20\\\"\", 'tx') + call assert_equal("\"breakdel file 20\t", @:) + call feedkeys(":breakdel file 20x\\\"\", 'tx') + call assert_equal("\"breakdel file 20x\t", @:) + call feedkeys(":breakdel file Xscript \\\"\", 'tx') + call assert_equal("\"breakdel file Xscript ", @:) + call feedkeys(":breakdel file X1B2C3\\\"\", 'tx') + call assert_equal("\"breakdel file X1B2C3", @:) + call delete('Xscript') + + " Test for :breakdel func [lnum] + func Xbreak_func() + endfunc + call feedkeys(":breakdel func Xbr\\\"\", 'tx') + call assert_equal("\"breakdel func Xbreak_func", @:) + call feedkeys(":breakdel func Xbr\\\"\", 'tx') + call assert_equal("\"breakdel func Xbreak_func", @:) + call feedkeys(":breakdel func 20 Xbr\\\"\", 'tx') + call assert_equal("\"breakdel func 20 Xbreak_func", @:) + call feedkeys(":breakdel func 20 Xbr\\\"\", 'tx') + call assert_equal("\"breakdel func 20 Xbreak_func", @:) + call feedkeys(":breakdel func 20x Xbr\\\"\", 'tx') + call assert_equal("\"breakdel func 20x Xbr\t", @:) + call feedkeys(":breakdel func 20\\\"\", 'tx') + call assert_equal("\"breakdel func 20\t", @:) + call feedkeys(":breakdel func 20x\\\"\", 'tx') + call assert_equal("\"breakdel func 20x\t", @:) + call feedkeys(":breakdel func Xbreak_func \\\"\", 'tx') + call assert_equal("\"breakdel func Xbreak_func ", @:) + call feedkeys(":breakdel func X1B2C3\\\"\", 'tx') + call assert_equal("\"breakdel func X1B2C3", @:) + delfunc Xbreak_func + + " Test for :breakdel here + call feedkeys(":breakdel here Xtest\\\"\", 'tx') + call assert_equal("\"breakdel here Xtest", @:) + call feedkeys(":breakdel here Xtest\\\"\", 'tx') + call assert_equal("\"breakdel here Xtest", @:) + call feedkeys(":breakdel here \\\"\", 'tx') + call assert_equal("\"breakdel here ", @:) + + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.4564/src/testdir/test_writefile.vim 2021-08-09 20:04:20.944157290 +0100 --- src/testdir/test_writefile.vim 2022-03-14 19:16:37.723994349 +0000 *************** *** 890,895 **** --- 890,898 ---- " link to the original file. The backup file should not be modified. func Test_write_backup_symlink() CheckUnix + call mkdir('Xbackup') + let save_backupdir = &backupdir + set backupdir=.,./Xbackup call writefile(['1111'], 'Xfile') silent !ln -s Xfile Xfile.bak *************** *** 898,908 **** write call assert_equal('link', getftype('Xfile.bak')) call assert_equal('Xfile', resolve('Xfile.bak')) set backup& backupcopy& backupext& ! close call delete('Xfile') call delete('Xfile.bak') endfunc " Test for ':write ++bin' and ':write ++nobin' --- 901,918 ---- write call assert_equal('link', getftype('Xfile.bak')) call assert_equal('Xfile', resolve('Xfile.bak')) + " backup file should be created in the 'backup' directory + if !has('bsd') + " This check fails on FreeBSD + call assert_true(filereadable('./Xbackup/Xfile.bak')) + endif set backup& backupcopy& backupext& ! %bw call delete('Xfile') call delete('Xfile.bak') + call delete('Xbackup', 'rf') + let &backupdir = save_backupdir endfunc " Test for ':write ++bin' and ':write ++nobin' *** ../vim-8.2.4564/src/version.c 2022-03-14 10:50:16.382185007 +0000 --- src/version.c 2022-03-14 19:18:14.484049345 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4565, /**/ -- hundred-and-one symptoms of being an internet addict: 257. Your "hundred-and-one" lists include well over 101 items, since you automatically interpret all numbers in hexadecimal notation. (hex 101 = decimal 257) /// 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 ///