Mercurial > vim
comparison src/search.c @ 3755:616bc1ad4f12 v7.3.636
updated for version 7.3.636
Problem: Not all zero-width matches handled correctly for "gn".
Solution: Move zero-width detection to a separate function. (Christian
Brabandt)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Thu, 23 Aug 2012 15:53:05 +0200 |
parents | f43ffd820a46 |
children | 29fe4e5c1db1 |
comparison
equal
deleted
inserted
replaced
3754:a69d2c9c76ee | 3755:616bc1ad4f12 |
---|---|
4524 } | 4524 } |
4525 | 4525 |
4526 #endif /* FEAT_TEXTOBJ */ | 4526 #endif /* FEAT_TEXTOBJ */ |
4527 | 4527 |
4528 #if defined(FEAT_VISUAL) || defined(PROTO) | 4528 #if defined(FEAT_VISUAL) || defined(PROTO) |
4529 static int is_zerowidth __ARGS((char_u *pattern)); | |
4530 | |
4529 /* | 4531 /* |
4530 * Find next search match under cursor, cursor at end. | 4532 * Find next search match under cursor, cursor at end. |
4531 * Used while an operator is pending, and in Visual mode. | 4533 * Used while an operator is pending, and in Visual mode. |
4532 * TODO: redo only works when used in operator pending mode | 4534 * TODO: redo only works when used in operator pending mode |
4533 */ | 4535 */ |
4544 int result; /* result of various function calls */ | 4546 int result; /* result of various function calls */ |
4545 char_u old_p_ws = p_ws; | 4547 char_u old_p_ws = p_ws; |
4546 int visual_active = FALSE; | 4548 int visual_active = FALSE; |
4547 int flags = 0; | 4549 int flags = 0; |
4548 pos_T save_VIsual; | 4550 pos_T save_VIsual; |
4549 regmmatch_T regmatch; | |
4550 int nmatched = 0; | |
4551 int zerowidth = FALSE; | 4551 int zerowidth = FALSE; |
4552 | |
4553 | 4552 |
4554 /* wrapping should not occur */ | 4553 /* wrapping should not occur */ |
4555 p_ws = FALSE; | 4554 p_ws = FALSE; |
4556 | 4555 |
4557 /* Correct cursor when 'selection' is exclusive */ | 4556 /* Correct cursor when 'selection' is exclusive */ |
4581 } | 4580 } |
4582 } | 4581 } |
4583 else | 4582 else |
4584 orig_pos = pos = start_pos = curwin->w_cursor; | 4583 orig_pos = pos = start_pos = curwin->w_cursor; |
4585 | 4584 |
4586 /* | 4585 /* Is the pattern is zero-width? */ |
4587 * Check for zero-width pattern. | 4586 zerowidth = is_zerowidth(spats[last_idx].pat); |
4588 */ | 4587 if (zerowidth == -1) |
4589 if (search_regcomp(spats[last_idx].pat, RE_SEARCH, RE_SEARCH, | |
4590 ((SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) | |
4591 return FAIL; | 4588 return FAIL; |
4592 | |
4593 /* Zero-width pattern should match somewhere, then we can check if start | |
4594 * and end are in the same position. */ | |
4595 nmatched = vim_regexec_multi(®match, curwin, curbuf, | |
4596 curwin->w_cursor.lnum, (colnr_T)0, NULL); | |
4597 if (called_emsg) | |
4598 return FAIL; | |
4599 if (nmatched && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum | |
4600 && regmatch.endpos[0].col == regmatch.startpos[0].col) | |
4601 zerowidth = TRUE; | |
4602 vim_free(regmatch.regprog); | |
4603 | 4589 |
4604 /* | 4590 /* |
4605 * The trick is to first search backwards and then search forward again, | 4591 * The trick is to first search backwards and then search forward again, |
4606 * so that a match at the current cursor position will be correctly | 4592 * so that a match at the current cursor position will be correctly |
4607 * captured. | 4593 * captured. |
4690 #endif | 4676 #endif |
4691 redraw_curbuf_later(INVERTED); | 4677 redraw_curbuf_later(INVERTED); |
4692 showmode(); | 4678 showmode(); |
4693 | 4679 |
4694 return OK; | 4680 return OK; |
4681 } | |
4682 | |
4683 /* | |
4684 * Check if the pattern is zero-width. | |
4685 * Returns TRUE, FALSE or -1 for failure. | |
4686 */ | |
4687 static int | |
4688 is_zerowidth(pattern) | |
4689 char_u *pattern; | |
4690 { | |
4691 regmmatch_T regmatch; | |
4692 int nmatched = 0; | |
4693 int result = -1; | |
4694 pos_T pos; | |
4695 | |
4696 if (search_regcomp(pattern, RE_SEARCH, RE_SEARCH, | |
4697 SEARCH_KEEP, ®match) == FAIL) | |
4698 return -1; | |
4699 | |
4700 /* move to match */ | |
4701 clearpos(&pos); | |
4702 if (searchit(curwin, curbuf, &pos, FORWARD, spats[last_idx].pat, 1, | |
4703 SEARCH_KEEP, RE_SEARCH, 0, NULL) != FAIL) | |
4704 { | |
4705 /* Zero-width pattern should match somewhere, then we can check if | |
4706 * start and end are in the same position. */ | |
4707 nmatched = vim_regexec_multi(®match, curwin, curbuf, | |
4708 pos.lnum, (colnr_T)0, NULL); | |
4709 | |
4710 if (!called_emsg) | |
4711 result = (nmatched != 0 | |
4712 && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum | |
4713 && regmatch.startpos[0].col == regmatch.endpos[0].col); | |
4714 } | |
4715 | |
4716 vim_free(regmatch.regprog); | |
4717 return result; | |
4695 } | 4718 } |
4696 #endif /* FEAT_VISUAL */ | 4719 #endif /* FEAT_VISUAL */ |
4697 | 4720 |
4698 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \ | 4721 #if defined(FEAT_LISP) || defined(FEAT_CINDENT) || defined(FEAT_TEXTOBJ) \ |
4699 || defined(PROTO) | 4722 || defined(PROTO) |