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)), &regmatch) == 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(&regmatch, 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