To: vim_dev@googlegroups.com Subject: Patch 7.4.984 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 7.4.984 Problem: searchpos() always starts searching in the first column, which is not what some people expect. (Brett Stahlman) Solution: Add the 'z' flag: start at the specified column. Files: src/vim.h, src/eval.c, src/search.c, src/testdir/test_searchpos.vim, src/testdir/test_alot.vim, runtime/doc/eval.txt *** ../vim-7.4.983/src/vim.h 2015-11-29 17:34:30.447580332 +0100 --- src/vim.h 2015-12-28 18:43:17.810204047 +0100 *************** *** 930,935 **** --- 930,936 ---- #define SEARCH_MARK 0x200 /* set previous context mark */ #define SEARCH_KEEP 0x400 /* keep previous search pattern */ #define SEARCH_PEEK 0x800 /* peek for typed char, cancel search */ + #define SEARCH_COL 0x1000 /* start at specified column instead of zero */ /* Values for find_ident_under_cursor() */ #define FIND_IDENT 1 /* find identifier (word) */ *** ../vim-7.4.983/src/eval.c 2015-12-13 14:45:16.543158883 +0100 --- src/eval.c 2015-12-28 18:47:27.011462855 +0100 *************** *** 16471,16476 **** --- 16471,16477 ---- #define SP_START 0x10 /* accept match at start position */ #define SP_SUBPAT 0x20 /* return nr of matching sub-pattern */ #define SP_END 0x40 /* leave cursor at end of match */ + #define SP_COLUMN 0x80 /* start at cursor column */ static int get_search_arg __ARGS((typval_T *varp, int *flagsp)); *************** *** 16512,16517 **** --- 16513,16519 ---- case 'p': mask = SP_SUBPAT; break; case 'r': mask = SP_REPEAT; break; case 's': mask = SP_SETPCMARK; break; + case 'z': mask = SP_COLUMN; break; } if (mask == 0) { *************** *** 16530,16536 **** } /* ! * Shared by search() and searchpos() functions */ static int search_cmn(argvars, match_pos, flagsp) --- 16532,16538 ---- } /* ! * Shared by search() and searchpos() functions. */ static int search_cmn(argvars, match_pos, flagsp) *************** *** 16562,16567 **** --- 16564,16571 ---- options |= SEARCH_START; if (flags & SP_END) options |= SEARCH_END; + if (flags & SP_COLUMN) + options |= SEARCH_COL; /* Optional arguments: line number to stop searching and timeout. */ if (argvars[1].v_type != VAR_UNKNOWN && argvars[2].v_type != VAR_UNKNOWN) *** ../vim-7.4.983/src/search.c 2015-09-01 18:27:45.117248852 +0200 --- src/search.c 2015-12-28 18:50:35.041394580 +0100 *************** *** 578,583 **** --- 578,584 ---- * if (options & SEARCH_KEEP) keep previous search pattern * if (options & SEARCH_FOLD) match only once in a closed fold * if (options & SEARCH_PEEK) check for typed char, cancel search + * if (options & SEARCH_COL) start at pos->col instead of zero * * Return FAIL (zero) for failure, non-zero for success. * When FEAT_EVAL is defined, returns the index of the first matching *************** *** 599,604 **** --- 600,606 ---- { int found; linenr_T lnum; /* no init to shut up Apollo cc */ + colnr_T col; regmmatch_T regmatch; char_u *ptr; colnr_T matchcol; *************** *** 711,722 **** /* * Look for a match somewhere in line "lnum". */ nmatched = vim_regexec_multi(®match, win, buf, ! lnum, (colnr_T)0, #ifdef FEAT_RELTIME ! tm #else ! NULL #endif ); /* Abort searching on an error (e.g., out of stack). */ --- 713,726 ---- /* * Look for a match somewhere in line "lnum". */ + col = at_first_line && (options & SEARCH_COL) ? pos->col + : (colnr_T)0; nmatched = vim_regexec_multi(®match, win, buf, ! lnum, col, #ifdef FEAT_RELTIME ! tm #else ! NULL #endif ); /* Abort searching on an error (e.g., out of stack). */ *************** *** 1098,1103 **** --- 1102,1108 ---- /* * Return the number of the first subpat that matched. + * Return zero if none of them matched. */ static int first_submatch(rp) *** ../vim-7.4.983/src/testdir/test_searchpos.vim 2015-12-28 19:16:19.348456356 +0100 --- src/testdir/test_searchpos.vim 2015-12-28 19:11:00.027953490 +0100 *************** *** 0 **** --- 1,28 ---- + " Tests for searchpos() + + func Test_searchpos() + new one + 0put ='1a3' + 1put ='123xyz' + call cursor(1, 1) + call assert_equal([1, 1, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')) + call cursor(1, 2) + call assert_equal([2, 1, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')) + set cpo-=c + call cursor(1, 2) + call assert_equal([1, 2, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')) + call cursor(1, 3) + call assert_equal([1, 3, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}xyz', 'pcW')) + + " Now with \zs, first match is in column 0, "a" is matched. + call cursor(1. 3) + call assert_equal([2, 4, 2], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcW')) + " With z flag start at cursor column, don't see the "a". + call cursor(1. 3) + call assert_equal([2, 4, 1], searchpos('\%(\([a-z]\)\|\_.\)\{-}\zsxyz', 'pcWz')) + + set cpo+=c + " close the window + q! + + endfunc *** ../vim-7.4.983/src/testdir/test_alot.vim 2015-12-03 16:54:21.970106719 +0100 --- src/testdir/test_alot.vim 2015-12-28 18:57:11.153037829 +0100 *************** *** 2,6 **** --- 2,7 ---- " This makes testing go faster, since Vim doesn't need to restart. source test_lispwords.vim + source test_searchpos.vim source test_sort.vim source test_undolevels.vim *** ../vim-7.4.983/runtime/doc/eval.txt 2015-12-03 16:32:52.724051746 +0100 --- runtime/doc/eval.txt 2015-12-28 19:15:28.681011267 +0100 *************** *** 5188,5201 **** move. No error message is given. {flags} is a String, which can contain these character flags: ! 'b' search backward instead of forward ! 'c' accept a match at the cursor position 'e' move to the End of the match 'n' do Not move the cursor ! 'p' return number of matching sub-pattern (see below) ! 's' set the ' mark at the previous location of the cursor ! 'w' wrap around the end of the file ! 'W' don't wrap around the end of the file If neither 'w' or 'W' is given, the 'wrapscan' option applies. If the 's' flag is supplied, the ' mark is set, only if the --- 5228,5242 ---- move. No error message is given. {flags} is a String, which can contain these character flags: ! 'b' search Backward instead of forward ! 'c' accept a match at the Cursor position 'e' move to the End of the match 'n' do Not move the cursor ! 'p' return number of matching sub-Pattern (see below) ! 's' Set the ' mark at the previous location of the cursor ! 'w' Wrap around the end of the file ! 'W' don't Wrap around the end of the file ! 'z' start searching at the cursor column instead of zero If neither 'w' or 'W' is given, the 'wrapscan' option applies. If the 's' flag is supplied, the ' mark is set, only if the *************** *** 5203,5208 **** --- 5244,5255 ---- flag. 'ignorecase', 'smartcase' and 'magic' are used. + + When the 'z' flag is not given seaching always starts in + column zero and then matches before the cursor are skipped. + When the 'c' flag is present in 'cpo' the next search starts + after the match. Without the 'c' flag the next search starts + one column further. When the {stopline} argument is given then the search stops after searching this line. This is useful to restrict the *** ../vim-7.4.983/src/version.c 2015-12-28 16:26:36.363773987 +0100 --- src/version.c 2015-12-28 18:56:55.769207005 +0100 *************** *** 743,744 **** --- 743,746 ---- { /* Add new patch number below this line */ + /**/ + 984, /**/ -- I still remember when I gave up Smoking, Drinking and Sex. It was the most *horrifying* hour of my life! /// 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 ///