search('multi-byte char', 'bce') does not match at cursor position.
Steps to reproduce:
$ vim -u NONE
:set encoding=utf-8
:call setline(1, "\uff21")
:echo search("\uff21", "bceW") " no wrap scan
0
Expected:
1
I think that the attached patch fixes this problem. Please check it.
For search("\uff21", "bce"), Vim checks if matched position is before the
start
position with this expression:
regmatch.endpos[0].col - 1 + extra_col <= start_pos.col
(extra_col = SEARCH_START ? 0 : 1)
normal boundary
| SEARCH_START boundary
<-| <-|
|0|1|2|3|
| A |
^ ^ ^
| | regmatch.endpos[0].col
| | LHS: regmatch.endpos[0].col - 1 + extra_col(1)
| LHS: regmatch.endpos[0].col - 1 + extra_col(0) (LHS<=RHS => false)
RHS: start_pos.col
This patch change it to:
regmatch.endpos[0].col - 1 < start_pos.col + extra_col
(extra_col = SEARCH_START ? len(A) : 0)
normal boundary
| SEARCH_START boundary
<-| <-|
|0|1|2|3|
| A |
^ ^ ^
| | regmatch.endpos[0].col
| | RHS: start_pos.col + extra_col(len(A)) (LHS<RHS => true)
| LHS: regmatch.endpos[0].col - 1
start_pos.col
RHS: start_pos.col + extra_col(0)
--
Yukihiro Nakadaira - [email protected]
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -r bfc3682510d6 src/search.c
--- a/src/search.c Sat Jul 04 15:05:14 2015 +0200
+++ b/src/search.c Thu Jul 09 21:28:34 2015 +0900
@@ -548,6 +548,7 @@
pos_T start_pos;
int at_first_line;
int extra_col;
+ int start_char_len;
int match_ok;
long nmatched;
int submatch = 0;
@@ -574,23 +575,37 @@
/* When not accepting a match at the start position set "extra_col" to
* a non-zero value. Don't do that when starting at MAXCOL, since
* MAXCOL + 1 is zero. */
- if ((options & SEARCH_START) || pos->col == MAXCOL)
- extra_col = 0;
+ if (pos->col == MAXCOL)
+ start_char_len = 0;
#ifdef FEAT_MBYTE
/* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */
- else if (dir != BACKWARD && has_mbyte
- && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
- && pos->col < MAXCOL - 2)
+ else if (has_mbyte
+ && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count
+ && pos->col < MAXCOL - 2)
{
ptr = ml_get_buf(buf, pos->lnum, FALSE) + pos->col;
if (*ptr == NUL)
- extra_col = 1;
+ start_char_len = 1;
else
- extra_col = (*mb_ptr2len)(ptr);
+ start_char_len = (*mb_ptr2len)(ptr);
}
#endif
else
- extra_col = 1;
+ start_char_len = 1;
+ if (dir == FORWARD)
+ {
+ if (options & SEARCH_START)
+ extra_col = 0;
+ else
+ extra_col = start_char_len;
+ }
+ else
+ {
+ if (options & SEARCH_START)
+ extra_col = start_char_len;
+ else
+ extra_col = 0;
+ }
start_pos = *pos; /* remember start pos for detecting no match */
found = 0; /* default: not found */
@@ -779,15 +794,15 @@
|| (lnum + regmatch.endpos[0].lnum
== start_pos.lnum
&& (int)regmatch.endpos[0].col - 1
- + extra_col
- <= (int)start_pos.col))
+ < (int)start_pos.col
+ + extra_col))
: (lnum + regmatch.startpos[0].lnum
< start_pos.lnum
|| (lnum + regmatch.startpos[0].lnum
== start_pos.lnum
&& (int)regmatch.startpos[0].col
- + extra_col
- <= (int)start_pos.col))))
+ < (int)start_pos.col
+ + extra_col))))
{
match_ok = TRUE;
matchpos = regmatch.startpos[0];
diff -r bfc3682510d6 src/testdir/test_search_bce_multibyte.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test_search_bce_multibyte.in Thu Jul 09 21:28:34 2015 +0900
@@ -0,0 +1,15 @@
+Test for search('multi-byte char', 'bce')
+
+STARTTEST
+:source small.vim
+:source mbyte.vim
+:set encoding=utf-8
+:/^Test bce:/+1
+:$put =search('A', 'bce', line('.'))
+:1;/^Results:/,$wq! test.out
+ENDTEST
+
+Results:
+
+Test bce:
+A
diff -r bfc3682510d6 src/testdir/test_search_bce_multibyte.ok
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/testdir/test_search_bce_multibyte.ok Thu Jul 09 21:28:34 2015 +0900
@@ -0,0 +1,5 @@
+Results:
+
+Test bce:
+A
+15