Mercurial > vim
comparison src/search.c @ 5064:8875401008da v7.3.1275
updated for version 7.3.1275
Problem: "gn" does not work when the match is a single character.
Solution: Fix it, add a test. (Christian Brabandt)
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Sun, 30 Jun 2013 14:46:53 +0200 |
parents | 66803af09906 |
children | 5569d11ef585 |
comparison
equal
deleted
inserted
replaced
5063:0b0bc666a439 | 5064:8875401008da |
---|---|
4487 } | 4487 } |
4488 | 4488 |
4489 #endif /* FEAT_TEXTOBJ */ | 4489 #endif /* FEAT_TEXTOBJ */ |
4490 | 4490 |
4491 #if defined(FEAT_VISUAL) || defined(PROTO) | 4491 #if defined(FEAT_VISUAL) || defined(PROTO) |
4492 static int is_zerowidth __ARGS((char_u *pattern)); | 4492 static int is_one_char __ARGS((char_u *pattern)); |
4493 | 4493 |
4494 /* | 4494 /* |
4495 * Find next search match under cursor, cursor at end. | 4495 * Find next search match under cursor, cursor at end. |
4496 * Used while an operator is pending, and in Visual mode. | 4496 * Used while an operator is pending, and in Visual mode. |
4497 * TODO: redo only works when used in operator pending mode | 4497 * TODO: redo only works when used in operator pending mode |
4508 int dir; | 4508 int dir; |
4509 int result; /* result of various function calls */ | 4509 int result; /* result of various function calls */ |
4510 char_u old_p_ws = p_ws; | 4510 char_u old_p_ws = p_ws; |
4511 int flags = 0; | 4511 int flags = 0; |
4512 pos_T save_VIsual; | 4512 pos_T save_VIsual; |
4513 int zerowidth = FALSE; | 4513 int one_char; |
4514 | 4514 |
4515 /* wrapping should not occur */ | 4515 /* wrapping should not occur */ |
4516 p_ws = FALSE; | 4516 p_ws = FALSE; |
4517 | 4517 |
4518 /* Correct cursor when 'selection' is exclusive */ | 4518 /* Correct cursor when 'selection' is exclusive */ |
4538 } | 4538 } |
4539 else | 4539 else |
4540 orig_pos = pos = start_pos = curwin->w_cursor; | 4540 orig_pos = pos = start_pos = curwin->w_cursor; |
4541 | 4541 |
4542 /* Is the pattern is zero-width? */ | 4542 /* Is the pattern is zero-width? */ |
4543 zerowidth = is_zerowidth(spats[last_idx].pat); | 4543 one_char = is_one_char(spats[last_idx].pat); |
4544 if (zerowidth == -1) | 4544 if (one_char == -1) |
4545 return FAIL; | 4545 return FAIL; /* invalid pattern */ |
4546 | 4546 |
4547 /* | 4547 /* |
4548 * The trick is to first search backwards and then search forward again, | 4548 * The trick is to first search backwards and then search forward again, |
4549 * so that a match at the current cursor position will be correctly | 4549 * so that a match at the current cursor position will be correctly |
4550 * captured. | 4550 * captured. |
4555 dir = i; | 4555 dir = i; |
4556 else | 4556 else |
4557 dir = !i; | 4557 dir = !i; |
4558 | 4558 |
4559 flags = 0; | 4559 flags = 0; |
4560 if (!dir && !zerowidth) | 4560 if (!dir && !one_char) |
4561 flags = SEARCH_END; | 4561 flags = SEARCH_END; |
4562 | 4562 |
4563 result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), | 4563 result = searchit(curwin, curbuf, &pos, (dir ? FORWARD : BACKWARD), |
4564 spats[last_idx].pat, (long) (i ? count : 1), | 4564 spats[last_idx].pat, (long) (i ? count : 1), |
4565 SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); | 4565 SEARCH_KEEP | flags, RE_SEARCH, 0, NULL); |
4596 start_pos = pos; | 4596 start_pos = pos; |
4597 flags = forward ? SEARCH_END : 0; | 4597 flags = forward ? SEARCH_END : 0; |
4598 | 4598 |
4599 /* move to match, except for zero-width matches, in which case, we are | 4599 /* move to match, except for zero-width matches, in which case, we are |
4600 * already on the next match */ | 4600 * already on the next match */ |
4601 if (!zerowidth) | 4601 if (!one_char) |
4602 result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), | 4602 result = searchit(curwin, curbuf, &pos, (forward ? FORWARD : BACKWARD), |
4603 spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); | 4603 spats[last_idx].pat, 0L, flags | SEARCH_KEEP, RE_SEARCH, 0, NULL); |
4604 | 4604 |
4605 if (!VIsual_active) | 4605 if (!VIsual_active) |
4606 VIsual = start_pos; | 4606 VIsual = start_pos; |
4643 | 4643 |
4644 return OK; | 4644 return OK; |
4645 } | 4645 } |
4646 | 4646 |
4647 /* | 4647 /* |
4648 * Check if the pattern is zero-width. | 4648 * Check if the pattern is one character or zero-width. |
4649 * Returns TRUE, FALSE or -1 for failure. | 4649 * Returns TRUE, FALSE or -1 for failure. |
4650 */ | 4650 */ |
4651 static int | 4651 static int |
4652 is_zerowidth(pattern) | 4652 is_one_char(pattern) |
4653 char_u *pattern; | 4653 char_u *pattern; |
4654 { | 4654 { |
4655 regmmatch_T regmatch; | 4655 regmmatch_T regmatch; |
4656 int nmatched = 0; | 4656 int nmatched = 0; |
4657 int result = -1; | 4657 int result = -1; |
4675 | 4675 |
4676 if (!called_emsg) | 4676 if (!called_emsg) |
4677 result = (nmatched != 0 | 4677 result = (nmatched != 0 |
4678 && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum | 4678 && regmatch.startpos[0].lnum == regmatch.endpos[0].lnum |
4679 && regmatch.startpos[0].col == regmatch.endpos[0].col); | 4679 && regmatch.startpos[0].col == regmatch.endpos[0].col); |
4680 | |
4681 if (!result && incl(&pos) == 0 && pos.col == regmatch.endpos[0].col) | |
4682 result = TRUE; | |
4680 } | 4683 } |
4681 | 4684 |
4682 called_emsg |= save_called_emsg; | 4685 called_emsg |= save_called_emsg; |
4683 vim_regfree(regmatch.regprog); | 4686 vim_regfree(regmatch.regprog); |
4684 return result; | 4687 return result; |