Mercurial > vim
comparison src/search.c @ 3732:f43ffd820a46 v7.3.625
updated for version 7.3.625
Problem: "gn" does not handle zero-width matches correctly.
Solution: Handle zero-width patterns specially. (Christian Brabandt)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 08 Aug 2012 15:27:57 +0200 |
parents | ac13ea2b098d |
children | 616bc1ad4f12 |
comparison
equal
deleted
inserted
replaced
3731:84ab759a9e38 | 3732:f43ffd820a46 |
---|---|
4544 int result; /* result of various function calls */ | 4544 int result; /* result of various function calls */ |
4545 char_u old_p_ws = p_ws; | 4545 char_u old_p_ws = p_ws; |
4546 int visual_active = FALSE; | 4546 int visual_active = FALSE; |
4547 int flags = 0; | 4547 int flags = 0; |
4548 pos_T save_VIsual; | 4548 pos_T save_VIsual; |
4549 regmmatch_T regmatch; | |
4550 int nmatched = 0; | |
4551 int zerowidth = FALSE; | |
4549 | 4552 |
4550 | 4553 |
4551 /* wrapping should not occur */ | 4554 /* wrapping should not occur */ |
4552 p_ws = FALSE; | 4555 p_ws = FALSE; |
4553 | 4556 |
4577 decl(&pos); | 4580 decl(&pos); |
4578 } | 4581 } |
4579 } | 4582 } |
4580 else | 4583 else |
4581 orig_pos = pos = start_pos = curwin->w_cursor; | 4584 orig_pos = pos = start_pos = curwin->w_cursor; |
4585 | |
4586 /* | |
4587 * Check for zero-width pattern. | |
4588 */ | |
4589 if (search_regcomp(spats[last_idx].pat, RE_SEARCH, RE_SEARCH, | |
4590 ((SEARCH_HIS + SEARCH_KEEP)), ®match) == FAIL) | |
4591 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); | |
4582 | 4603 |
4583 /* | 4604 /* |
4584 * The trick is to first search backwards and then search forward again, | 4605 * The trick is to first search backwards and then search forward again, |
4585 * so that a match at the current cursor position will be correctly | 4606 * so that a match at the current cursor position will be correctly |
4586 * captured. | 4607 * captured. |
4587 */ | 4608 */ |
4588 for (i = 0; i < 2; i++) | 4609 for (i = 0; i < 2; i++) |
4589 { | 4610 { |
4590 if (i && count == 1) | |
4591 flags = SEARCH_START; | |
4592 | |
4593 if (forward) | 4611 if (forward) |
4594 dir = i; | 4612 dir = i; |
4595 else | 4613 else |
4596 dir = !i; | 4614 dir = !i; |
4615 | |
4616 flags = 0; | |
4617 if (!dir && !zerowidth) | |
4618 flags = SEARCH_END; | |
4619 | |
4597 result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), | 4620 result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), |
4598 spats[last_idx].pat, (long) (i ? count : 1), | 4621 spats[last_idx].pat, (long) (i ? count : 1), |
4599 SEARCH_KEEP | flags | (dir ? 0 : SEARCH_END), | 4622 SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); |
4600 RE_SEARCH, 0, NULL); | |
4601 | 4623 |
4602 /* First search may fail, but then start searching from the | 4624 /* First search may fail, but then start searching from the |
4603 * beginning of the file (cursor might be on the search match) | 4625 * beginning of the file (cursor might be on the search match) |
4604 * except when Visual mode is active, so that extending the visual | 4626 * except when Visual mode is active, so that extending the visual |
4605 * selection works. */ | 4627 * selection works. */ |
4627 } | 4649 } |
4628 | 4650 |
4629 } | 4651 } |
4630 | 4652 |
4631 start_pos = pos; | 4653 start_pos = pos; |
4632 flags = (forward ? SEARCH_END : 0); | 4654 flags = forward ? SEARCH_END : 0; |
4633 | 4655 |
4634 /* move to match */ | 4656 /* move to match, except for zero-width matches, in which case, we are |
4635 result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), | 4657 * already on the next match */ |
4658 if (!zerowidth) | |
4659 result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), | |
4636 spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); | 4660 spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); |
4637 | 4661 |
4638 if (!VIsual_active) | 4662 if (!VIsual_active) |
4639 VIsual = start_pos; | 4663 VIsual = start_pos; |
4640 | 4664 |