vim-patch:8.1.1390: search stats are off when using count or offset

Problem:    Search stats are off when using count or offset.
Solution:   Recompute the stats when needed. (Masato Nishihata, closes vim/vim#4410)
8f46e4c4bd
This commit is contained in:
erw7
2019-05-27 17:08:29 +09:00
parent 2d567ac47e
commit ec671c7048
2 changed files with 44 additions and 16 deletions

View File

@@ -1000,6 +1000,7 @@ int do_search(
char_u *ps; char_u *ps;
char_u *msgbuf = NULL; char_u *msgbuf = NULL;
size_t len; size_t len;
bool has_offset = false;
#define SEARCH_STAT_BUF_LEN 12 #define SEARCH_STAT_BUF_LEN 12
/* /*
@@ -1280,7 +1281,9 @@ int do_search(
* Add character and/or line offset * Add character and/or line offset
*/ */
if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) { if (!(options & SEARCH_NOOF) || (pat != NULL && *pat == ';')) {
if (spats[0].off.line) { /* Add the offset to the line number. */ pos_T org_pos = pos;
if (spats[0].off.line) { // Add the offset to the line number.
c = pos.lnum + spats[0].off.off; c = pos.lnum + spats[0].off.off;
if (c < 1) if (c < 1)
pos.lnum = 1; pos.lnum = 1;
@@ -1306,6 +1309,9 @@ int do_search(
break; break;
} }
} }
if (!equalpos(pos, org_pos)) {
has_offset = true;
}
} }
// Show [1/15] if 'S' is not in 'shortmess'. // Show [1/15] if 'S' is not in 'shortmess'.
@@ -1315,7 +1321,8 @@ int do_search(
&& c != FAIL && c != FAIL
&& !shortmess(SHM_SEARCHCOUNT) && !shortmess(SHM_SEARCHCOUNT)
&& msgbuf != NULL) { && msgbuf != NULL) {
search_stat(dirc, &pos, show_top_bot_msg, msgbuf); search_stat(dirc, &pos, show_top_bot_msg, msgbuf,
(count != 1 || has_offset));
} }
// The search command can be followed by a ';' to do another search. // The search command can be followed by a ';' to do another search.
@@ -4199,8 +4206,9 @@ int linewhite(linenr_T lnum)
} }
// Add the search count "[3/19]" to "msgbuf". // Add the search count "[3/19]" to "msgbuf".
// When "recompute" is true Always recompute the numbers.
static void search_stat(int dirc, pos_T *pos, static void search_stat(int dirc, pos_T *pos,
bool show_top_bot_msg, char_u *msgbuf) bool show_top_bot_msg, char_u *msgbuf, bool recompute)
{ {
int save_ws = p_ws; int save_ws = p_ws;
int wraparound = false; int wraparound = false;
@@ -4224,7 +4232,8 @@ static void search_stat(int dirc, pos_T *pos,
&& STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0 && STRNICMP(lastpat, spats[last_idx].pat, STRLEN(lastpat)) == 0
&& STRLEN(lastpat) == STRLEN(spats[last_idx].pat) && STRLEN(lastpat) == STRLEN(spats[last_idx].pat)
&& equalpos(lastpos, curwin->w_cursor) && equalpos(lastpos, curwin->w_cursor)
&& lbuf == curbuf) || wraparound || cur < 0 || cur > 99) { && lbuf == curbuf)
|| wraparound || cur < 0 || cur > 99 || recompute) {
cur = 0; cur = 0;
cnt = 0; cnt = 0;
clearpos(&lastpos); clearpos(&lastpos);

View File

@@ -11,7 +11,7 @@ func! Test_search_stat()
" Append 50 lines with text to search for, "foobar" appears 20 times " Append 50 lines with text to search for, "foobar" appears 20 times
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10)) call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 10))
" 1) match at second line " match at second line
call cursor(1, 1) call cursor(1, 1)
let @/ = 'fo*\(bar\?\)\?' let @/ = 'fo*\(bar\?\)\?'
let g:a = execute(':unsilent :norm! n') let g:a = execute(':unsilent :norm! n')
@@ -19,13 +19,13 @@ func! Test_search_stat()
let pat = escape(@/, '()*?'). '\s\+' let pat = escape(@/, '()*?'). '\s\+'
call assert_match(pat .. stat, g:a) call assert_match(pat .. stat, g:a)
" 2) Match at last line " Match at last line
call cursor(line('$')-2, 1) call cursor(line('$')-2, 1)
let g:a = execute(':unsilent :norm! n') let g:a = execute(':unsilent :norm! n')
let stat = '\[50/50\]' let stat = '\[50/50\]'
call assert_match(pat .. stat, g:a) call assert_match(pat .. stat, g:a)
" 3) No search stat " No search stat
set shortmess+=S set shortmess+=S
call cursor(1, 1) call cursor(1, 1)
let stat = '\[2/50\]' let stat = '\[2/50\]'
@@ -33,7 +33,7 @@ func! Test_search_stat()
call assert_notmatch(pat .. stat, g:a) call assert_notmatch(pat .. stat, g:a)
set shortmess-=S set shortmess-=S
" 4) Many matches " Many matches
call cursor(line('$')-2, 1) call cursor(line('$')-2, 1)
let @/ = '.' let @/ = '.'
let pat = escape(@/, '()*?'). '\s\+' let pat = escape(@/, '()*?'). '\s\+'
@@ -45,7 +45,7 @@ func! Test_search_stat()
let stat = '\[1/>99\] W' let stat = '\[1/>99\] W'
call assert_match(pat .. stat, g:a) call assert_match(pat .. stat, g:a)
" 5) Many matches " Many matches
call cursor(1, 1) call cursor(1, 1)
let g:a = execute(':unsilent :norm! n') let g:a = execute(':unsilent :norm! n')
let stat = '\[2/>99\]' let stat = '\[2/>99\]'
@@ -55,7 +55,7 @@ func! Test_search_stat()
let stat = '\[>99/>99\] W' let stat = '\[>99/>99\] W'
call assert_match(pat .. stat, g:a) call assert_match(pat .. stat, g:a)
" 6) right-left " right-left
if exists("+rightleft") if exists("+rightleft")
set rl set rl
call cursor(1,1) call cursor(1,1)
@@ -67,7 +67,7 @@ func! Test_search_stat()
set norl set norl
endif endif
" 7) right-left bottom " right-left bottom
if exists("+rightleft") if exists("+rightleft")
set rl set rl
call cursor('$',1) call cursor('$',1)
@@ -78,7 +78,7 @@ func! Test_search_stat()
set norl set norl
endif endif
" 8) right-left back at top " right-left back at top
if exists("+rightleft") if exists("+rightleft")
set rl set rl
call cursor('$',1) call cursor('$',1)
@@ -90,7 +90,7 @@ func! Test_search_stat()
set norl set norl
endif endif
" 9) normal, back at bottom " normal, back at bottom
call cursor(1,1) call cursor(1,1)
let @/ = 'foobar' let @/ = 'foobar'
let pat = '?foobar\s\+' let pat = '?foobar\s\+'
@@ -100,7 +100,7 @@ func! Test_search_stat()
call assert_match('search hit TOP, continuing at BOTTOM', g:a) call assert_match('search hit TOP, continuing at BOTTOM', g:a)
call assert_match('\[20/20\] W', Screenline(&lines)) call assert_match('\[20/20\] W', Screenline(&lines))
" 10) normal, no match " normal, no match
call cursor(1,1) call cursor(1,1)
let @/ = 'zzzzzz' let @/ = 'zzzzzz'
let g:a = '' let g:a = ''
@@ -114,7 +114,26 @@ func! Test_search_stat()
call assert_false(1) call assert_false(1)
endtry endtry
" 11) normal, n comes from a mapping " with count
call cursor(1, 1)
let @/ = 'fo*\(bar\?\)\?'
let g:a = execute(':unsilent :norm! 2n')
let stat = '\[3/50\]'
let pat = escape(@/, '()*?'). '\s\+'
call assert_match(pat .. stat, g:a)
let g:a = execute(':unsilent :norm! 2n')
let stat = '\[5/50\]'
call assert_match(pat .. stat, g:a)
" with offset
call cursor(1, 1)
call feedkeys("/fo*\\(bar\\?\\)\\?/+1\<cr>", 'tx')
let g:a = execute(':unsilent :norm! n')
let stat = '\[5/50\]'
let pat = escape(@/ .. '/+1', '()*?'). '\s\+'
call assert_match(pat .. stat, g:a)
" normal, n comes from a mapping
" Need to move over more than 64 lines to trigger char_avail(. " Need to move over more than 64 lines to trigger char_avail(.
nnoremap n nzv nnoremap n nzv
call cursor(1,1) call cursor(1,1)
@@ -130,7 +149,7 @@ func! Test_search_stat()
call assert_match(pat .. stat, g:b) call assert_match(pat .. stat, g:b)
unmap n unmap n
" 11) normal, but silent " normal, but silent
call cursor(1,1) call cursor(1,1)
let @/ = 'find this' let @/ = 'find this'
let pat = '/find this\s\+' let pat = '/find this\s\+'