patch 9.1.1535: the maximum search count uses hard-coded value 99
Problem: The maximum search count uses a hard-coded value of 99
(Andres Monge, Joschua Kesper)
Solution: Make it configurable using the 'maxsearchcount' option.
related: #8855
fixes: #17527
closes: #17695
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
23
src/option.c
23
src/option.c
@ -4138,6 +4138,29 @@ did_set_scrollbind(optset_T *args UNUSED)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process the new 'maxsearchcount' option value.
|
||||
*/
|
||||
char *
|
||||
did_set_maxsearchcount(optset_T *args UNUSED)
|
||||
{
|
||||
char *errmsg = NULL;
|
||||
// if you increase this, also increase SEARCH_STAT_BUF_LEN in search.c
|
||||
#define MAX_SEARCH_COUNT 9999
|
||||
|
||||
if (p_msc <= 0)
|
||||
errmsg = e_argument_must_be_positive;
|
||||
else if (p_msc > MAX_SEARCH_COUNT)
|
||||
errmsg = e_invalid_argument;
|
||||
|
||||
if (errmsg != NULL)
|
||||
p_msc = 99;
|
||||
|
||||
return errmsg;
|
||||
#undef MAX_SEARCH_COUNT
|
||||
}
|
||||
|
||||
|
||||
#if defined(BACKSLASH_IN_FILENAME) || defined(PROTO)
|
||||
/*
|
||||
* Process the updated 'shellslash' option value.
|
||||
|
||||
@ -792,6 +792,7 @@ EXTERN long p_mmt; // 'maxmemtot'
|
||||
EXTERN long p_mis; // 'menuitems'
|
||||
#endif
|
||||
EXTERN char_u *p_mopt; // 'messagesopt'
|
||||
EXTERN long p_msc; // 'maxsearchcount'
|
||||
#ifdef FEAT_SPELL
|
||||
EXTERN char_u *p_msm; // 'mkspellmem'
|
||||
#endif
|
||||
|
||||
@ -1733,6 +1733,9 @@ static struct vimoption options[] =
|
||||
(char_u *)&p_mmt, PV_NONE, NULL, NULL,
|
||||
{(char_u *)DFLT_MAXMEMTOT, (char_u *)0L}
|
||||
SCTX_INIT},
|
||||
{"maxsearchcount", "msc", P_NUM|P_VI_DEF,
|
||||
(char_u *)&p_msc, PV_NONE, did_set_maxsearchcount, NULL,
|
||||
{(char_u *)99L, (char_u *)0L} SCTX_INIT},
|
||||
{"menuitems", "mis", P_NUM|P_VI_DEF,
|
||||
#ifdef FEAT_MENU
|
||||
(char_u *)&p_mis, PV_NONE, NULL, NULL,
|
||||
|
||||
@ -65,6 +65,7 @@ char *did_set_pyxversion(optset_T *args);
|
||||
char *did_set_readonly(optset_T *args);
|
||||
char *did_set_scrollbind(optset_T *args);
|
||||
char *did_set_shellslash(optset_T *args);
|
||||
char *did_set_maxsearchcount(optset_T *args);
|
||||
char *did_set_shiftwidth_tabstop(optset_T *args);
|
||||
char *did_set_showtabline(optset_T *args);
|
||||
char *did_set_smoothscroll(optset_T *args);
|
||||
|
||||
13
src/search.c
13
src/search.c
@ -55,8 +55,9 @@ static int fuzzy_match_func_compare(const void *s1, const void *s2);
|
||||
static void fuzzy_match_func_sort(fuzmatch_str_T *fm, int sz);
|
||||
|
||||
#define SEARCH_STAT_DEF_TIMEOUT 40L
|
||||
#define SEARCH_STAT_DEF_MAX_COUNT 99
|
||||
#define SEARCH_STAT_BUF_LEN 12
|
||||
// 'W ': 2 +
|
||||
// '[>9999/>9999]': 13 + 1 (NUL)
|
||||
#define SEARCH_STAT_BUF_LEN 16
|
||||
|
||||
/*
|
||||
* This file contains various searching-related routines. These fall into
|
||||
@ -1696,7 +1697,7 @@ do_search(
|
||||
NULL, NULL))
|
||||
#endif
|
||||
),
|
||||
SEARCH_STAT_DEF_MAX_COUNT,
|
||||
p_msc,
|
||||
SEARCH_STAT_DEF_TIMEOUT);
|
||||
|
||||
/*
|
||||
@ -3265,7 +3266,7 @@ update_search_stat(
|
||||
static int cnt = 0;
|
||||
static int exact_match = FALSE;
|
||||
static int incomplete = 0;
|
||||
static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
|
||||
static int last_maxcount = 0;
|
||||
static int chgtick = 0;
|
||||
static char_u *lastpat = NULL;
|
||||
static size_t lastpatlen = 0;
|
||||
@ -3282,7 +3283,7 @@ update_search_stat(
|
||||
stat->cnt = cnt;
|
||||
stat->exact_match = exact_match;
|
||||
stat->incomplete = incomplete;
|
||||
stat->last_maxcount = last_maxcount;
|
||||
stat->last_maxcount = p_msc;
|
||||
return;
|
||||
}
|
||||
last_maxcount = maxcount;
|
||||
@ -4174,7 +4175,7 @@ f_searchcount(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
pos_T pos = curwin->w_cursor;
|
||||
char_u *pattern = NULL;
|
||||
int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
|
||||
int maxcount = p_msc;
|
||||
long timeout = SEARCH_STAT_DEF_TIMEOUT;
|
||||
int recompute = TRUE;
|
||||
searchstat_T stat;
|
||||
|
||||
@ -477,4 +477,166 @@ func Test_search_stat_smartcase_ignorecase()
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
func Test_search_stat_option_values()
|
||||
call assert_fails(':set maxsearchcount=0', 'E487:')
|
||||
call assert_fails(':set maxsearchcount=10000', 'E474:')
|
||||
set maxsearchcount=9999
|
||||
call assert_equal(9999, &msc)
|
||||
set maxsearchcount=1
|
||||
call assert_equal(1, &msc)
|
||||
set maxsearchcount=999
|
||||
call assert_equal(999, &msc)
|
||||
set maxsearchcount&vim
|
||||
endfunc
|
||||
|
||||
func Test_search_stat_option()
|
||||
" Asan causes wrong results, because the search times out
|
||||
CheckNotAsan
|
||||
enew
|
||||
set shortmess-=S
|
||||
set maxsearchcount=999
|
||||
" Append 1000 lines with text to search for, "foobar" appears 20 times
|
||||
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 1000))
|
||||
|
||||
call cursor(1, 1)
|
||||
call assert_equal(
|
||||
\ #{exact_match: 1, current: 1, incomplete: 2, maxcount: 999, total: 1000},
|
||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 1, 0]}))
|
||||
" on last char of match
|
||||
call assert_equal(
|
||||
\ #{exact_match: 1, current: 1, incomplete: 2, maxcount: 999, total: 1000},
|
||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 9, 0]}))
|
||||
" on char after match
|
||||
call assert_equal(
|
||||
\ #{exact_match: 0, current: 1, incomplete: 2, maxcount: 999, total: 1000},
|
||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 10, 0]}))
|
||||
|
||||
" match at second line
|
||||
let messages_before = execute('messages')
|
||||
let @/ = 'fo*\(bar\?\)\?'
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[2/>999\]'
|
||||
let pat = escape(@/, '()*?'). '\s\+'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call assert_equal(
|
||||
\ #{exact_match: 1, current: 2, incomplete: 2, maxcount: 999, total: 1000},
|
||||
\ searchcount(#{recompute: 0}))
|
||||
" didn't get added to message history
|
||||
call assert_equal(messages_before, execute('messages'))
|
||||
|
||||
" Many matches
|
||||
call cursor(line('$')-2, 1)
|
||||
let @/ = '.'
|
||||
let pat = escape(@/, '()*?'). '\s\+'
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[>999/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call assert_equal(
|
||||
\ #{exact_match: 0, current: 1000, incomplete: 2, maxcount: 999, total: 1000},
|
||||
\ searchcount(#{recompute: 0}))
|
||||
call assert_equal(
|
||||
\ #{exact_match: 1, current: 27992, incomplete: 0, maxcount:0, total: 28000},
|
||||
\ searchcount(#{recompute: v:true, maxcount: 0, timeout: 200}))
|
||||
call assert_equal(
|
||||
\ #{exact_match: 1, current: 1, incomplete: 0, maxcount: 0, total: 28000},
|
||||
\ searchcount(#{recompute: 1, maxcount: 0, pos: [1, 1, 0], timeout: 200}))
|
||||
call cursor(line('$'), 1)
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = 'W \[1/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call assert_equal(
|
||||
\ #{current: 1, exact_match: 1, total: 1000, incomplete: 2, maxcount: 999},
|
||||
\ searchcount(#{recompute: 0}))
|
||||
call assert_equal(
|
||||
\ #{current: 1, exact_match: 1, total: 28000, incomplete: 0, maxcount: 0},
|
||||
\ searchcount(#{recompute: 1, maxcount: 0, timeout: 200}))
|
||||
call assert_equal(
|
||||
\ #{current: 27991, exact_match: 1, total: 28000, incomplete: 0, maxcount: 0},
|
||||
\ searchcount(#{recompute: 1, maxcount: 0, pos: [line('$')-2, 1, 0], timeout: 200}))
|
||||
|
||||
" Many matches
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[2/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! N')
|
||||
let stat = '\[>999/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
set maxsearchcount=500
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[2/>500\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! N')
|
||||
let stat = '\[>500/>500\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
set maxsearchcount=20
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[2/>20\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call cursor(1, 1)
|
||||
let g:a = execute(':unsilent :norm! N')
|
||||
let stat = '\[>20/>20\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
set maxsearchcount=999
|
||||
|
||||
" right-left
|
||||
if exists("+rightleft")
|
||||
set rl
|
||||
call cursor(1,1)
|
||||
let @/ = 'foobar'
|
||||
let pat = 'raboof/\s\+'
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = '\[>999/2\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
|
||||
" right-left bottom
|
||||
call cursor('$',1)
|
||||
let pat = 'raboof?\s\+'
|
||||
let g:a = execute(':unsilent :norm! N')
|
||||
let stat = '\[>999/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
|
||||
" right-left back at top
|
||||
call cursor('$',1)
|
||||
let pat = 'raboof/\s\+'
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
let stat = 'W \[>999/1\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
set norl
|
||||
endif
|
||||
|
||||
" normal, back at bottom
|
||||
call cursor(1,1)
|
||||
let @/ = 'foobar'
|
||||
let pat = '?foobar\s\+'
|
||||
let g:a = execute(':unsilent :norm! N')
|
||||
let stat = 'W \[>999/>999\]'
|
||||
call assert_match(pat .. stat, g:a)
|
||||
call assert_match('W \[>999/>999\]', Screenline(&lines))
|
||||
|
||||
" normal, no match
|
||||
call cursor(1,1)
|
||||
let @/ = 'zzzzzz'
|
||||
let g:a = ''
|
||||
try
|
||||
let g:a = execute(':unsilent :norm! n')
|
||||
catch /^Vim\%((\a\+)\)\=:E486/
|
||||
let stat = ''
|
||||
" error message is not redir'ed to g:a, it is empty
|
||||
call assert_true(empty(g:a))
|
||||
catch
|
||||
call assert_false(1)
|
||||
endtry
|
||||
|
||||
" Clean up
|
||||
set shortmess+=S
|
||||
set maxsearchcount&vim
|
||||
" close the window
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@ -279,6 +279,7 @@ let test_values = {
|
||||
\ 'renderoptions': [[''], ['xxx']],
|
||||
\ 'rightleftcmd': [['search'], ['xxx']],
|
||||
\ 'rulerformat': [['', 'xxx'], ['%-', '%(', '%15(%%']],
|
||||
\ 'maxsearchcount': [[1, 10, 100, 1000], [0, -1, 10000]],
|
||||
\ 'selection': [['old', 'inclusive', 'exclusive'], ['', 'xxx']],
|
||||
\ 'selectmode': [['', 'mouse', 'key', 'cmd', 'key,cmd'], ['xxx']],
|
||||
\ 'sessionoptions': [['', 'blank', 'curdir', 'sesdir',
|
||||
|
||||
@ -719,6 +719,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1535,
|
||||
/**/
|
||||
1534,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user