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