diff --git a/7.4.813 b/7.4.813 new file mode 100644 index 0000000..f05962e --- /dev/null +++ b/7.4.813 @@ -0,0 +1,646 @@ +To: vim_dev@googlegroups.com +Subject: Patch 7.4.813 +Fcc: outbox +From: Bram Moolenaar +Mime-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +------------ + +Patch 7.4.813 +Problem: It is not possible to save and restore character search state. +Solution: Add getcharsearch() and setcharsearch(). (James McCoy) +Files: runtime/doc/eval.txt, src/eval.c, src/proto/search.pro, + src/search.c, src/testdir/test_charsearch.in, + src/testdir/test_charsearch.ok, src/testdir/Makefile, + src/testdir/Make_amiga.mak, src/testdir/Make_dos.mak, + src/testdir/Make_ming.mak, src/testdir/Make_os2.mak, + src/testdir/Make_vms.mms + + +*** ../vim-7.4.812/runtime/doc/eval.txt 2015-07-21 15:48:13.581518028 +0200 +--- runtime/doc/eval.txt 2015-08-11 13:32:31.643435417 +0200 +*************** +*** 1820,1828 **** + any variable {varname} in buffer {expr} + getchar( [expr]) Number get one character from the user + getcharmod( ) Number modifiers for the last typed character + getcmdline() String return the current command-line + getcmdpos() Number return cursor position in command-line +! getcmdtype() String return the current command-line type + getcurpos() List position of the cursor + getcwd() String the current working directory + getfontname( [{name}]) String name of font being used +--- 1822,1832 ---- + any variable {varname} in buffer {expr} + getchar( [expr]) Number get one character from the user + getcharmod( ) Number modifiers for the last typed character ++ getcharsearch() Dict last character search + getcmdline() String return the current command-line + getcmdpos() Number return cursor position in command-line +! getcmdtype() String return current command-line type +! getcmdwintype() String return current command-line window type + getcurpos() List position of the cursor + getcwd() String the current working directory + getfontname( [{name}]) String name of font being used +*************** +*** 1968,1973 **** +--- 1972,1978 ---- + Number send reply string + serverlist() String get a list of available servers + setbufvar( {expr}, {varname}, {val}) set {varname} in buffer {expr} to {val} ++ setcharsearch( {dict}) Dict set character search from {dict} + setcmdpos( {pos}) Number set cursor position in command-line + setline( {lnum}, {line}) Number set line {lnum} to {line} + setloclist( {nr}, {list}[, {action}]) +*************** +*** 3334,3339 **** +--- 3363,3388 ---- + character itself are obtained. Thus Shift-a results in "A" + without a modifier. + ++ getcharsearch() *getcharsearch()* ++ Return the current character search information as a {dict} ++ with the following entries: ++ ++ char character previously used for a character ++ search (|t|, |f|, |T|, or |F|); empty string ++ if no character search has been performed ++ forward direction of character search; 1 for forward, ++ 0 for backward ++ until type of character search; 1 for a |t| or |T| ++ character search, 0 for an |f| or |F| ++ character search ++ ++ This can be useful to always have |;| and |,| search ++ forward/backward regardless of the direction of the previous ++ character search: > ++ :nnoremap ; getcharsearch().forward ? ';' : ',' ++ :nnoremap , getcharsearch().forward ? ',' : ';' ++ < Also see |setcharsearch()|. ++ + getcmdline() *getcmdline()* + Return the current command-line. Only works when the command + line is being edited, thus requires use of |c_CTRL-\_e| or +*************** +*** 5356,5361 **** +--- 5419,5444 ---- + :call setbufvar("todo", "myvar", "foobar") + < This function is not available in the |sandbox|. + ++ setcharsearch() *setcharsearch()* ++ Set the current character search information to {dict}, ++ which contains one or more of the following entries: ++ ++ char character which will be used for a subsequent ++ |,| or |;| command; an empty string clears the ++ character search ++ forward direction of character search; 1 for forward, ++ 0 for backward ++ until type of character search; 1 for a |t| or |T| ++ character search, 0 for an |f| or |F| ++ character search ++ ++ This can be useful to save/restore a user's character search ++ from a script: > ++ :let prevsearch = getcharsearch() ++ :" Perform a command which clobbers user's search ++ :call setcharsearch(prevsearch) ++ < Also see |getcharsearch()|. ++ + setcmdpos({pos}) *setcmdpos()* + Set the cursor position in the command line to byte position + {pos}. The first position is 1. +*** ../vim-7.4.812/src/eval.c 2015-07-21 15:48:13.585517990 +0200 +--- src/eval.c 2015-08-11 13:34:03.374392656 +0200 +*************** +*** 555,560 **** +--- 555,561 ---- + static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_getchar __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_getcharmod __ARGS((typval_T *argvars, typval_T *rettv)); ++ static void f_getcharsearch __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_getcmdline __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_getcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_getcmdtype __ARGS((typval_T *argvars, typval_T *rettv)); +*************** +*** 688,693 **** +--- 689,695 ---- + static void f_server2client __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_serverlist __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_setbufvar __ARGS((typval_T *argvars, typval_T *rettv)); ++ static void f_setcharsearch __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_setcmdpos __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_setline __ARGS((typval_T *argvars, typval_T *rettv)); + static void f_setloclist __ARGS((typval_T *argvars, typval_T *rettv)); +*************** +*** 8149,8154 **** +--- 8151,8157 ---- + {"getbufvar", 2, 3, f_getbufvar}, + {"getchar", 0, 1, f_getchar}, + {"getcharmod", 0, 0, f_getcharmod}, ++ {"getcharsearch", 0, 0, f_getcharsearch}, + {"getcmdline", 0, 0, f_getcmdline}, + {"getcmdpos", 0, 0, f_getcmdpos}, + {"getcmdtype", 0, 0, f_getcmdtype}, +*************** +*** 8285,8290 **** +--- 8288,8294 ---- + {"server2client", 2, 2, f_server2client}, + {"serverlist", 0, 0, f_serverlist}, + {"setbufvar", 3, 3, f_setbufvar}, ++ {"setcharsearch", 1, 1, f_setcharsearch}, + {"setcmdpos", 1, 1, f_setcmdpos}, + {"setline", 2, 2, f_setline}, + {"setloclist", 2, 3, f_setloclist}, +*************** +*** 11664,11669 **** +--- 11668,11691 ---- + } + + /* ++ * "getcharsearch()" function ++ */ ++ static void ++ f_getcharsearch(argvars, rettv) ++ typval_T *argvars UNUSED; ++ typval_T *rettv; ++ { ++ if (rettv_dict_alloc(rettv) != FAIL) ++ { ++ dict_T *dict = rettv->vval.v_dict; ++ ++ dict_add_nr_str(dict, "char", 0L, last_csearch()); ++ dict_add_nr_str(dict, "forward", last_csearch_forward(), NULL); ++ dict_add_nr_str(dict, "until", last_csearch_until(), NULL); ++ } ++ } ++ ++ /* + * "getcmdline()" function + */ + static void +*************** +*** 17004,17009 **** +--- 17026,17073 ---- + } + } + ++ static void ++ f_setcharsearch(argvars, rettv) ++ typval_T *argvars; ++ typval_T *rettv UNUSED; ++ { ++ dict_T *d; ++ dictitem_T *di; ++ char_u *csearch; ++ ++ if (argvars[0].v_type != VAR_DICT) ++ { ++ EMSG(_(e_dictreq)); ++ return; ++ } ++ ++ if ((d = argvars[0].vval.v_dict) != NULL) ++ { ++ csearch = get_dict_string(d, (char_u *)"char", FALSE); ++ if (csearch != NULL) ++ { ++ if (enc_utf8) ++ { ++ int pcc[MAX_MCO]; ++ int c = utfc_ptr2char(csearch, pcc); ++ set_last_csearch(c, csearch, utfc_ptr2len(csearch)); ++ } ++ else ++ set_last_csearch(mb_ptr2char(csearch), ++ csearch, mb_ptr2len(csearch)); ++ } ++ ++ di = dict_find(d, (char_u *)"forward", -1); ++ if (di != NULL) ++ set_csearch_direction(get_tv_number(&di->di_tv) ++ ? FORWARD : BACKWARD); ++ ++ di = dict_find(d, (char_u *)"until", -1); ++ if (di != NULL) ++ set_csearch_until(!!get_tv_number(&di->di_tv)); ++ } ++ } ++ + /* + * "setcmdpos()" function + */ +*** ../vim-7.4.812/src/proto/search.pro 2014-12-13 03:17:07.465046539 +0100 +--- src/proto/search.pro 2015-08-11 13:32:31.651435327 +0200 +*************** +*** 8,13 **** +--- 8,19 ---- + void free_search_patterns __ARGS((void)); + int ignorecase __ARGS((char_u *pat)); + int pat_has_uppercase __ARGS((char_u *pat)); ++ char_u *last_csearch __ARGS((void)); ++ int last_csearch_forward __ARGS((void)); ++ int last_csearch_until __ARGS((void)); ++ void set_last_csearch __ARGS((int c, char_u *s, int len)); ++ void set_csearch_direction __ARGS((int cdir)); ++ void set_csearch_until __ARGS((int t_cmd)); + char_u *last_search_pat __ARGS((void)); + void reset_search_dir __ARGS((void)); + void set_last_search_pat __ARGS((char_u *s, int idx, int magic, int setlast)); +*** ../vim-7.4.812/src/search.c 2015-07-28 21:17:31.518069428 +0200 +--- src/search.c 2015-08-11 14:05:25.425003350 +0200 +*************** +*** 89,94 **** +--- 89,102 ---- + + static int last_idx = 0; /* index in spats[] for RE_LAST */ + ++ static char_u lastc[2] = {NUL, NUL}; /* last character searched for */ ++ static int lastcdir = FORWARD; /* last direction of character search */ ++ static int last_t_cmd = TRUE; /* last search t_cmd */ ++ #ifdef FEAT_MBYTE ++ static char_u lastc_bytes[MB_MAXBYTES + 1]; ++ static int lastc_bytelen = 1; /* >1 for multi-byte char */ ++ #endif ++ + #if defined(FEAT_AUTOCMD) || defined(FEAT_EVAL) || defined(PROTO) + /* copy of spats[], for keeping the search patterns while executing autocmds */ + static struct spat saved_spats[2]; +*************** +*** 378,384 **** + } + + /* +! * Return TRUE if patter "pat" has an uppercase character. + */ + int + pat_has_uppercase(pat) +--- 386,392 ---- + } + + /* +! * Return TRUE if pattern "pat" has an uppercase character. + */ + int + pat_has_uppercase(pat) +*************** +*** 419,424 **** +--- 427,484 ---- + } + + char_u * ++ last_csearch() ++ { ++ #ifdef FEAT_MBYTE ++ return lastc_bytes; ++ #else ++ return lastc; ++ #endif ++ } ++ ++ int ++ last_csearch_forward() ++ { ++ return lastcdir == FORWARD; ++ } ++ ++ int ++ last_csearch_until() ++ { ++ return last_t_cmd == TRUE; ++ } ++ ++ void ++ set_last_csearch(c, s, len) ++ int c; ++ char_u *s; ++ int len; ++ { ++ *lastc = c; ++ #ifdef FEAT_MBYTE ++ lastc_bytelen = len; ++ if (len) ++ memcpy(lastc_bytes, s, len); ++ else ++ vim_memset(lastc_bytes, 0, sizeof(lastc_bytes)); ++ #endif ++ } ++ ++ void ++ set_csearch_direction(cdir) ++ int cdir; ++ { ++ lastcdir = cdir; ++ } ++ ++ void ++ set_csearch_until(t_cmd) ++ int t_cmd; ++ { ++ last_t_cmd = t_cmd; ++ } ++ ++ char_u * + last_search_pat() + { + return spats[last_idx].pat; +*************** +*** 1559,1605 **** + int c = cap->nchar; /* char to search for */ + int dir = cap->arg; /* TRUE for searching forward */ + long count = cap->count1; /* repeat count */ +- static int lastc = NUL; /* last character searched for */ +- static int lastcdir; /* last direction of character search */ +- static int last_t_cmd; /* last search t_cmd */ + int col; + char_u *p; + int len; + int stop = TRUE; +- #ifdef FEAT_MBYTE +- static char_u bytes[MB_MAXBYTES + 1]; +- static int bytelen = 1; /* >1 for multi-byte char */ +- #endif + + if (c != NUL) /* normal search: remember args for repeat */ + { + if (!KeyStuffed) /* don't remember when redoing */ + { +! lastc = c; +! lastcdir = dir; +! last_t_cmd = t_cmd; + #ifdef FEAT_MBYTE +! bytelen = (*mb_char2bytes)(c, bytes); + if (cap->ncharC1 != 0) + { +! bytelen += (*mb_char2bytes)(cap->ncharC1, bytes + bytelen); + if (cap->ncharC2 != 0) +! bytelen += (*mb_char2bytes)(cap->ncharC2, bytes + bytelen); + } + #endif + } + } + else /* repeat previous search */ + { +! if (lastc == NUL) + return FAIL; + if (dir) /* repeat in opposite direction */ + dir = -lastcdir; + else + dir = lastcdir; + t_cmd = last_t_cmd; +! c = lastc; +! /* For multi-byte re-use last bytes[] and bytelen. */ + + /* Force a move of at least one char, so ";" and "," will move the + * cursor, even if the cursor is right in front of char we are looking +--- 1619,1660 ---- + int c = cap->nchar; /* char to search for */ + int dir = cap->arg; /* TRUE for searching forward */ + long count = cap->count1; /* repeat count */ + int col; + char_u *p; + int len; + int stop = TRUE; + + if (c != NUL) /* normal search: remember args for repeat */ + { + if (!KeyStuffed) /* don't remember when redoing */ + { +! *lastc = c; +! set_csearch_direction(dir); +! set_csearch_until(t_cmd); + #ifdef FEAT_MBYTE +! lastc_bytelen = (*mb_char2bytes)(c, lastc_bytes); + if (cap->ncharC1 != 0) + { +! lastc_bytelen += (*mb_char2bytes)(cap->ncharC1, +! lastc_bytes + lastc_bytelen); + if (cap->ncharC2 != 0) +! lastc_bytelen += (*mb_char2bytes)(cap->ncharC2, +! lastc_bytes + lastc_bytelen); + } + #endif + } + } + else /* repeat previous search */ + { +! if (*lastc == NUL) + return FAIL; + if (dir) /* repeat in opposite direction */ + dir = -lastcdir; + else + dir = lastcdir; + t_cmd = last_t_cmd; +! c = *lastc; +! /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */ + + /* Force a move of at least one char, so ";" and "," will move the + * cursor, even if the cursor is right in front of char we are looking +*************** +*** 1636,1649 **** + return FAIL; + col -= (*mb_head_off)(p, p + col - 1) + 1; + } +! if (bytelen == 1) + { + if (p[col] == c && stop) + break; + } + else + { +! if (vim_memcmp(p + col, bytes, bytelen) == 0 && stop) + break; + } + stop = TRUE; +--- 1691,1704 ---- + return FAIL; + col -= (*mb_head_off)(p, p + col - 1) + 1; + } +! if (lastc_bytelen == 1) + { + if (p[col] == c && stop) + break; + } + else + { +! if (vim_memcmp(p + col, lastc_bytes, lastc_bytelen) == 0 && stop) + break; + } + stop = TRUE; +*************** +*** 1671,1678 **** + if (has_mbyte) + { + if (dir < 0) +! /* Landed on the search char which is bytelen long */ +! col += bytelen - 1; + else + /* To previous char, which may be multi-byte. */ + col -= (*mb_head_off)(p, p + col); +--- 1726,1733 ---- + if (has_mbyte) + { + if (dir < 0) +! /* Landed on the search char which is lastc_bytelen long */ +! col += lastc_bytelen - 1; + else + /* To previous char, which may be multi-byte. */ + col -= (*mb_head_off)(p, p + col); +*** ../vim-7.4.812/src/testdir/test_charsearch.in 2015-08-11 14:22:29.713361737 +0200 +--- src/testdir/test_charsearch.in 2015-08-11 14:12:34.048131520 +0200 +*************** +*** 0 **** +--- 1,25 ---- ++ Test for character searches ++ ++ STARTTEST ++ :so small.vim ++ :" check that "fe" and ";" work ++ /^X ++ ylfep;;p,,p: ++ :" check that save/restore works ++ /^Y ++ ylfep:let csave = getcharsearch() ++ fip:call setcharsearch(csave) ++ ;p;p: ++ :" check that setcharsearch() changes the settins. ++ /^Z ++ ylfep:call setcharsearch({'char': 'k'}) ++ ;p:call setcharsearch({'forward': 0}) ++ $;p:call setcharseearch({'until'}: 1}) ++ ;;p: ++ :/^X/,$w! test.out ++ :qa! ++ ENDTEST ++ ++ Xabcdefghijkemnopqretuvwxyz ++ Yabcdefghijkemnopqretuvwxyz ++ Zabcdefghijkemnokqretkvwxyz +*** ../vim-7.4.812/src/testdir/test_charsearch.ok 2015-08-11 14:22:29.717361691 +0200 +--- src/testdir/test_charsearch.ok 2015-08-11 13:59:20.253153843 +0200 +*************** +*** 0 **** +--- 1,3 ---- ++ XabcdeXfghijkeXmnopqreXtuvwxyz ++ YabcdeYfghiYjkeYmnopqreYtuvwxyz ++ ZabcdeZfghijkZemnokZqretkZvwxyz +*** ../vim-7.4.812/src/testdir/Makefile 2015-07-21 15:48:13.593517912 +0200 +--- src/testdir/Makefile 2015-08-11 13:46:04.386197622 +0200 +*************** +*** 39,44 **** +--- 39,45 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*** ../vim-7.4.812/src/testdir/Make_amiga.mak 2015-07-21 15:48:13.589517950 +0200 +--- src/testdir/Make_amiga.mak 2015-08-11 13:45:21.702682710 +0200 +*************** +*** 42,47 **** +--- 42,48 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*************** +*** 194,199 **** +--- 195,201 ---- + test_autoformat_join.out: test_autoformat_join.in + test_breakindent.out: test_breakindent.in + test_changelist.out: test_changelist.in ++ test_charsearch.out: test_charsearch.in + test_close_count.out: test_close_count.in + test_command_count.out: test_command_count.in + test_erasebackword.out: test_erasebackword.in +*** ../vim-7.4.812/src/testdir/Make_dos.mak 2015-07-21 15:48:13.589517950 +0200 +--- src/testdir/Make_dos.mak 2015-08-11 13:45:29.306596293 +0200 +*************** +*** 41,46 **** +--- 41,47 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*** ../vim-7.4.812/src/testdir/Make_ming.mak 2015-07-21 15:48:13.589517950 +0200 +--- src/testdir/Make_ming.mak 2015-08-11 13:45:35.742523150 +0200 +*************** +*** 63,68 **** +--- 63,69 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*** ../vim-7.4.812/src/testdir/Make_os2.mak 2015-07-21 15:48:13.593517912 +0200 +--- src/testdir/Make_os2.mak 2015-08-11 14:23:59.096345955 +0200 +*************** +*** 43,48 **** +--- 43,49 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*** ../vim-7.4.812/src/testdir/Make_vms.mms 2015-07-21 15:48:13.593517912 +0200 +--- src/testdir/Make_vms.mms 2015-08-11 14:24:20.772099626 +0200 +*************** +*** 4,10 **** + # Authors: Zoltan Arpadffy, + # Sandor Kopanyi, + # +! # Last change: 2015 Jul 17 + # + # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. + # Edit the lines in the Configuration section below to select. +--- 4,10 ---- + # Authors: Zoltan Arpadffy, + # Sandor Kopanyi, + # +! # Last change: 2015 Aug 11 + # + # This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64. + # Edit the lines in the Configuration section below to select. +*************** +*** 102,107 **** +--- 102,108 ---- + test_autoformat_join.out \ + test_breakindent.out \ + test_changelist.out \ ++ test_charsearch.out \ + test_close_count.out \ + test_command_count.out \ + test_erasebackword.out \ +*** ../vim-7.4.812/src/version.c 2015-08-08 18:23:41.219566256 +0200 +--- src/version.c 2015-08-11 13:22:49.398054460 +0200 +*************** +*** 743,744 **** +--- 743,746 ---- + { /* Add new patch number below this line */ ++ /**/ ++ 813, + /**/ + +-- +`When any government, or any church for that matter, undertakes to say to + its subjects, "This you may not read, this you must not see, this you are + forbidden to know," the end result is tyranny and oppression no matter how + holy the motives' -- Robert A Heinlein, "If this goes on --" + + /// 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 ///