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;