mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
vim-patch:9.1.1535: the maximum search count uses hard-coded value 99 (#34873)
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: vim/vim#8855
fixes: vim/vim#17527
closes: vim/vim#17695
b7b7fa04bf
Co-authored-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
@ -233,6 +233,7 @@ OPTIONS
|
|||||||
• 'completeopt' flag "nearset" sorts completion results by distance to cursor.
|
• 'completeopt' flag "nearset" sorts completion results by distance to cursor.
|
||||||
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
• 'diffopt' `inline:` configures diff highlighting for changes within a line.
|
||||||
• 'grepformat' is now a |global-local| option.
|
• 'grepformat' is now a |global-local| option.
|
||||||
|
• 'maxsearchcount' sets maximum value for |searchcount()| and defaults to 999.
|
||||||
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
• 'pummaxwidth' sets maximum width for the completion popup menu.
|
||||||
• 'winborder' "bold" style, custom border style.
|
• 'winborder' "bold" style, custom border style.
|
||||||
• |g:clipboard| accepts a string name to force any builtin clipboard tool.
|
• |g:clipboard| accepts a string name to force any builtin clipboard tool.
|
||||||
@ -296,7 +297,6 @@ These existing features changed their behavior.
|
|||||||
• 'spellfile' location defaults to `stdpath("data").."/site/spell/"` instead of
|
• 'spellfile' location defaults to `stdpath("data").."/site/spell/"` instead of
|
||||||
the first writable directory in 'runtimepath'.
|
the first writable directory in 'runtimepath'.
|
||||||
• |vim.version.range()| doesn't exclude `to` if it is equal to `from`.
|
• |vim.version.range()| doesn't exclude `to` if it is equal to `from`.
|
||||||
• |searchcount()|'s maximal value is raised from 99 to 999.
|
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
REMOVED FEATURES *news-removed*
|
REMOVED FEATURES *news-removed*
|
||||||
|
@ -4286,6 +4286,15 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
Vim may run out of memory before hitting the 'maxmempattern' limit, in
|
Vim may run out of memory before hitting the 'maxmempattern' limit, in
|
||||||
which case you get an "Out of memory" error instead.
|
which case you get an "Out of memory" error instead.
|
||||||
|
|
||||||
|
*'maxsearchcount'* *'msc'*
|
||||||
|
'maxsearchcount' 'msc' number (default 999)
|
||||||
|
global
|
||||||
|
Maximum number of matches shown for the search count status |shm-S|
|
||||||
|
When the number of matches exceeds this value, Vim shows ">" instead
|
||||||
|
of the exact count to keep searching fast.
|
||||||
|
Note: larger values may impact performance.
|
||||||
|
The value must be between 1 and 9999.
|
||||||
|
|
||||||
*'menuitems'* *'mis'*
|
*'menuitems'* *'mis'*
|
||||||
'menuitems' 'mis' number (default 25)
|
'menuitems' 'mis' number (default 25)
|
||||||
global
|
global
|
||||||
@ -5681,7 +5690,8 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
is shown), the "search hit BOTTOM, continuing at TOP" and
|
is shown), the "search hit BOTTOM, continuing at TOP" and
|
||||||
"search hit TOP, continuing at BOTTOM" messages are only
|
"search hit TOP, continuing at BOTTOM" messages are only
|
||||||
indicated by a "W" (Mnemonic: Wrapped) letter before the
|
indicated by a "W" (Mnemonic: Wrapped) letter before the
|
||||||
search count statistics.
|
search count statistics. The maximum limit can be set with
|
||||||
|
the 'maxsearchcount' option.
|
||||||
|
|
||||||
This gives you the opportunity to avoid that a change between buffers
|
This gives you the opportunity to avoid that a change between buffers
|
||||||
requires you to hit <Enter>, but still gives as useful a message as
|
requires you to hit <Enter>, but still gives as useful a message as
|
||||||
|
@ -176,6 +176,7 @@ The following options affect how a search is performed in Vim:
|
|||||||
'ignorecase' ignore case when searching
|
'ignorecase' ignore case when searching
|
||||||
'imsearch' use IME when entering the search pattern
|
'imsearch' use IME when entering the search pattern
|
||||||
'incsearch' show matches incrementally as the pattern is typed
|
'incsearch' show matches incrementally as the pattern is typed
|
||||||
|
'maxsearchcount' maximum number for the search count |shm-S|
|
||||||
'shortmess' suppress messages |shm-s|; show search count |shm-S|
|
'shortmess' suppress messages |shm-s|; show search count |shm-S|
|
||||||
'smartcase' override 'ignorecase' if pattern contains uppercase
|
'smartcase' override 'ignorecase' if pattern contains uppercase
|
||||||
'wrapscan' continue searching from the start of the file
|
'wrapscan' continue searching from the start of the file
|
||||||
|
@ -69,6 +69,7 @@ Defaults *defaults* *nvim-defaults*
|
|||||||
- 'langremap' is disabled
|
- 'langremap' is disabled
|
||||||
- 'laststatus' defaults to 2 (statusline is always shown)
|
- 'laststatus' defaults to 2 (statusline is always shown)
|
||||||
- 'listchars' defaults to "tab:> ,trail:-,nbsp:+"
|
- 'listchars' defaults to "tab:> ,trail:-,nbsp:+"
|
||||||
|
- 'maxsearchcount' defaults t0 999
|
||||||
- 'mouse' defaults to "nvi", see |default-mouse| for details
|
- 'mouse' defaults to "nvi", see |default-mouse| for details
|
||||||
- 'mousemodel' defaults to "popup_setpos"
|
- 'mousemodel' defaults to "popup_setpos"
|
||||||
- 'nrformats' defaults to "bin,hex"
|
- 'nrformats' defaults to "bin,hex"
|
||||||
@ -340,7 +341,6 @@ Functions:
|
|||||||
- |matchadd()| can be called before highlight group is defined
|
- |matchadd()| can be called before highlight group is defined
|
||||||
- |tempname()| tries to recover if the Nvim |tempdir| disappears.
|
- |tempname()| tries to recover if the Nvim |tempdir| disappears.
|
||||||
- |writefile()| with "p" flag creates parent directories.
|
- |writefile()| with "p" flag creates parent directories.
|
||||||
- |searchcount()|'s maximal value is raised from 99 to 999.
|
|
||||||
- |prompt_getinput()|
|
- |prompt_getinput()|
|
||||||
|
|
||||||
Highlight groups:
|
Highlight groups:
|
||||||
|
15
runtime/lua/vim/_meta/options.lua
generated
15
runtime/lua/vim/_meta/options.lua
generated
@ -4351,6 +4351,18 @@ vim.o.mmp = vim.o.maxmempattern
|
|||||||
vim.go.maxmempattern = vim.o.maxmempattern
|
vim.go.maxmempattern = vim.o.maxmempattern
|
||||||
vim.go.mmp = vim.go.maxmempattern
|
vim.go.mmp = vim.go.maxmempattern
|
||||||
|
|
||||||
|
--- Maximum number of matches shown for the search count status `shm-S`
|
||||||
|
--- When the number of matches exceeds this value, Vim shows ">" instead
|
||||||
|
--- of the exact count to keep searching fast.
|
||||||
|
--- Note: larger values may impact performance.
|
||||||
|
--- The value must be between 1 and 9999.
|
||||||
|
---
|
||||||
|
--- @type integer
|
||||||
|
vim.o.maxsearchcount = 999
|
||||||
|
vim.o.msc = vim.o.maxsearchcount
|
||||||
|
vim.go.maxsearchcount = vim.o.maxsearchcount
|
||||||
|
vim.go.msc = vim.go.maxsearchcount
|
||||||
|
|
||||||
--- Maximum number of items to use in a menu. Used for menus that are
|
--- Maximum number of items to use in a menu. Used for menus that are
|
||||||
--- generated from a list of items, e.g., the Buffers menu. Changing this
|
--- generated from a list of items, e.g., the Buffers menu. Changing this
|
||||||
--- option has no direct effect, the menu must be refreshed first.
|
--- option has no direct effect, the menu must be refreshed first.
|
||||||
@ -6004,7 +6016,8 @@ vim.bo.sw = vim.bo.shiftwidth
|
|||||||
--- is shown), the "search hit BOTTOM, continuing at TOP" and
|
--- is shown), the "search hit BOTTOM, continuing at TOP" and
|
||||||
--- "search hit TOP, continuing at BOTTOM" messages are only
|
--- "search hit TOP, continuing at BOTTOM" messages are only
|
||||||
--- indicated by a "W" (Mnemonic: Wrapped) letter before the
|
--- indicated by a "W" (Mnemonic: Wrapped) letter before the
|
||||||
--- search count statistics.
|
--- search count statistics. The maximum limit can be set with
|
||||||
|
--- the 'maxsearchcount' option.
|
||||||
---
|
---
|
||||||
--- This gives you the opportunity to avoid that a change between buffers
|
--- This gives you the opportunity to avoid that a change between buffers
|
||||||
--- requires you to hit <Enter>, but still gives as useful a message as
|
--- requires you to hit <Enter>, but still gives as useful a message as
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
" These commands create the option window.
|
" These commands create the option window.
|
||||||
"
|
"
|
||||||
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
" Maintainer: The Vim Project <https://github.com/vim/vim>
|
||||||
" Last Change: 2025 Apr 24
|
" Last Change: 2025 Jul 10
|
||||||
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
" Former Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||||
|
|
||||||
" If there already is an option window, jump to that one.
|
" If there already is an option window, jump to that one.
|
||||||
@ -261,6 +261,8 @@ call <SID>AddOption("ignorecase", gettext("ignore case when using a search patte
|
|||||||
call <SID>BinOptionG("ic", &ic)
|
call <SID>BinOptionG("ic", &ic)
|
||||||
call <SID>AddOption("smartcase", gettext("override 'ignorecase' when pattern has upper case characters"))
|
call <SID>AddOption("smartcase", gettext("override 'ignorecase' when pattern has upper case characters"))
|
||||||
call <SID>BinOptionG("scs", &scs)
|
call <SID>BinOptionG("scs", &scs)
|
||||||
|
call <SID>AddOption("maxsearchcount", gettext("Maximum number for the search count feature"))
|
||||||
|
call <SID>OptionG("msc", &msc)
|
||||||
call <SID>AddOption("casemap", gettext("what method to use for changing case of letters"))
|
call <SID>AddOption("casemap", gettext("what method to use for changing case of letters"))
|
||||||
call <SID>OptionG("cmp", &cmp)
|
call <SID>OptionG("cmp", &cmp)
|
||||||
call <SID>AddOption("maxmempattern", gettext("maximum amount of memory in Kbyte used for pattern matching"))
|
call <SID>AddOption("maxmempattern", gettext("maximum amount of memory in Kbyte used for pattern matching"))
|
||||||
|
@ -2840,6 +2840,9 @@ static const char *validate_num_option(OptIndex opt_idx, OptInt *newval, char *e
|
|||||||
return e_invarg;
|
return e_invarg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if you increase this, also increase SEARCH_STAT_BUF_LEN in search.c
|
||||||
|
enum { MAX_SEARCH_COUNT = 9999, };
|
||||||
|
|
||||||
switch (opt_idx) {
|
switch (opt_idx) {
|
||||||
case kOptHelpheight:
|
case kOptHelpheight:
|
||||||
case kOptTitlelen:
|
case kOptTitlelen:
|
||||||
@ -2972,6 +2975,13 @@ static const char *validate_num_option(OptIndex opt_idx, OptInt *newval, char *e
|
|||||||
return e_cannot_have_more_than_hundred_quickfix;
|
return e_cannot_have_more_than_hundred_quickfix;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kOptMaxsearchcount:
|
||||||
|
if (value <= 0) {
|
||||||
|
return e_positive;
|
||||||
|
} else if (value > MAX_SEARCH_COUNT) {
|
||||||
|
return e_invarg;
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -413,6 +413,7 @@ EXTERN OptInt p_mmd; ///< 'maxmapdepth'
|
|||||||
EXTERN OptInt p_mmp; ///< 'maxmempattern'
|
EXTERN OptInt p_mmp; ///< 'maxmempattern'
|
||||||
EXTERN OptInt p_mis; ///< 'menuitems'
|
EXTERN OptInt p_mis; ///< 'menuitems'
|
||||||
EXTERN char *p_mopt; ///< 'messagesopt'
|
EXTERN char *p_mopt; ///< 'messagesopt'
|
||||||
|
EXTERN OptInt p_msc; ///< 'maxsearchcount'
|
||||||
EXTERN char *p_msm; ///< 'mkspellmem'
|
EXTERN char *p_msm; ///< 'mkspellmem'
|
||||||
EXTERN int p_ml; ///< 'modeline'
|
EXTERN int p_ml; ///< 'modeline'
|
||||||
EXTERN int p_mle; ///< 'modelineexpr'
|
EXTERN int p_mle; ///< 'modelineexpr'
|
||||||
|
@ -5655,6 +5655,22 @@ local options = {
|
|||||||
type = 'number',
|
type = 'number',
|
||||||
varname = 'p_mmp',
|
varname = 'p_mmp',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
abbreviation = 'msc',
|
||||||
|
defaults = 999,
|
||||||
|
desc = [=[
|
||||||
|
Maximum number of matches shown for the search count status |shm-S|
|
||||||
|
When the number of matches exceeds this value, Vim shows ">" instead
|
||||||
|
of the exact count to keep searching fast.
|
||||||
|
Note: larger values may impact performance.
|
||||||
|
The value must be between 1 and 9999.
|
||||||
|
]=],
|
||||||
|
full_name = 'maxsearchcount',
|
||||||
|
scope = { 'global' },
|
||||||
|
short_desc = N_('maximum number for the search count feature'),
|
||||||
|
type = 'number',
|
||||||
|
varname = 'p_msc',
|
||||||
|
},
|
||||||
{
|
{
|
||||||
abbreviation = 'mis',
|
abbreviation = 'mis',
|
||||||
defaults = 25,
|
defaults = 25,
|
||||||
@ -7884,7 +7900,8 @@ local options = {
|
|||||||
is shown), the "search hit BOTTOM, continuing at TOP" and
|
is shown), the "search hit BOTTOM, continuing at TOP" and
|
||||||
"search hit TOP, continuing at BOTTOM" messages are only
|
"search hit TOP, continuing at BOTTOM" messages are only
|
||||||
indicated by a "W" (Mnemonic: Wrapped) letter before the
|
indicated by a "W" (Mnemonic: Wrapped) letter before the
|
||||||
search count statistics.
|
search count statistics. The maximum limit can be set with
|
||||||
|
the 'maxsearchcount' option.
|
||||||
|
|
||||||
This gives you the opportunity to avoid that a change between buffers
|
This gives you the opportunity to avoid that a change between buffers
|
||||||
requires you to hit <Enter>, but still gives as useful a message as
|
requires you to hit <Enter>, but still gives as useful a message as
|
||||||
|
@ -1427,7 +1427,7 @@ int do_search(oparg_T *oap, int dirc, int search_delim, char *pat, size_t patlen
|
|||||||
|| (!(fdo_flags & kOptFdoFlagSearch)
|
|| (!(fdo_flags & kOptFdoFlagSearch)
|
||||||
&& hasFolding(curwin, curwin->w_cursor.lnum, NULL,
|
&& hasFolding(curwin, curwin->w_cursor.lnum, NULL,
|
||||||
NULL))),
|
NULL))),
|
||||||
SEARCH_STAT_DEF_MAX_COUNT,
|
(int)p_msc,
|
||||||
SEARCH_STAT_DEF_TIMEOUT);
|
SEARCH_STAT_DEF_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,7 +2704,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
|||||||
static int cnt = 0;
|
static int cnt = 0;
|
||||||
static bool exact_match = false;
|
static bool exact_match = false;
|
||||||
static int incomplete = 0;
|
static int incomplete = 0;
|
||||||
static int last_maxcount = SEARCH_STAT_DEF_MAX_COUNT;
|
static int last_maxcount = 0;
|
||||||
static int chgtick = 0;
|
static int chgtick = 0;
|
||||||
static char *lastpat = NULL;
|
static char *lastpat = NULL;
|
||||||
static size_t lastpatlen = 0;
|
static size_t lastpatlen = 0;
|
||||||
@ -2717,7 +2717,7 @@ static void update_search_stat(int dirc, pos_T *pos, pos_T *cursor_pos, searchst
|
|||||||
stat->cnt = cnt;
|
stat->cnt = cnt;
|
||||||
stat->exact_match = exact_match;
|
stat->exact_match = exact_match;
|
||||||
stat->incomplete = incomplete;
|
stat->incomplete = incomplete;
|
||||||
stat->last_maxcount = last_maxcount;
|
stat->last_maxcount = (int)p_msc;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
last_maxcount = maxcount;
|
last_maxcount = maxcount;
|
||||||
@ -2801,7 +2801,7 @@ void f_searchcount(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
|||||||
{
|
{
|
||||||
pos_T pos = curwin->w_cursor;
|
pos_T pos = curwin->w_cursor;
|
||||||
char *pattern = NULL;
|
char *pattern = NULL;
|
||||||
int maxcount = SEARCH_STAT_DEF_MAX_COUNT;
|
int maxcount = (int)p_msc;
|
||||||
int timeout = SEARCH_STAT_DEF_TIMEOUT;
|
int timeout = SEARCH_STAT_DEF_TIMEOUT;
|
||||||
bool recompute = true;
|
bool recompute = true;
|
||||||
searchstat_T stat;
|
searchstat_T stat;
|
||||||
|
@ -63,8 +63,9 @@ enum {
|
|||||||
|
|
||||||
// Values for searchcount()
|
// Values for searchcount()
|
||||||
enum { SEARCH_STAT_DEF_TIMEOUT = 40, };
|
enum { SEARCH_STAT_DEF_TIMEOUT = 40, };
|
||||||
enum { SEARCH_STAT_DEF_MAX_COUNT = 999, };
|
// 'W ': 2 +
|
||||||
enum { SEARCH_STAT_BUF_LEN = 14, };
|
// '[>9999/>9999]': 13 + 1 (NUL)
|
||||||
|
enum { SEARCH_STAT_BUF_LEN = 16, };
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
/// Maximum number of characters that can be fuzzy matched
|
/// Maximum number of characters that can be fuzzy matched
|
||||||
|
@ -638,7 +638,7 @@ describe('ui/ext_messages', function()
|
|||||||
{10:line} 2 |
|
{10:line} 2 |
|
||||||
{1:~ }|*3
|
{1:~ }|*3
|
||||||
]],
|
]],
|
||||||
messages = { { content = { { '/line W [1/2]' } }, kind = 'search_count' } },
|
messages = { { content = { { '/line W [1/2]' } }, kind = 'search_count' } },
|
||||||
}
|
}
|
||||||
|
|
||||||
feed('n')
|
feed('n')
|
||||||
@ -648,7 +648,7 @@ describe('ui/ext_messages', function()
|
|||||||
{10:^line} 2 |
|
{10:^line} 2 |
|
||||||
{1:~ }|*3
|
{1:~ }|*3
|
||||||
]],
|
]],
|
||||||
messages = { { content = { { '/line [2/2]' } }, kind = 'search_count' } },
|
messages = { { content = { { '/line [2/2]' } }, kind = 'search_count' } },
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
@ -308,6 +308,7 @@ let test_values = {
|
|||||||
"\ 'renderoptions': [[''], ['xxx']],
|
"\ 'renderoptions': [[''], ['xxx']],
|
||||||
\ 'rightleftcmd': [['search'], ['xxx']],
|
\ 'rightleftcmd': [['search'], ['xxx']],
|
||||||
\ 'rulerformat': [['', 'xxx'], ['%-', '%(', '%15(%%']],
|
\ 'rulerformat': [['', 'xxx'], ['%-', '%(', '%15(%%']],
|
||||||
|
\ 'maxsearchcount': [[1, 10, 100, 1000], [0, -1, 10000]],
|
||||||
\ 'selection': [['old', 'inclusive', 'exclusive'], ['', 'xxx']],
|
\ 'selection': [['old', 'inclusive', 'exclusive'], ['', 'xxx']],
|
||||||
\ 'selectmode': [['', 'mouse', 'key', 'cmd', 'key,cmd'], ['xxx']],
|
\ 'selectmode': [['', 'mouse', 'key', 'cmd', 'key,cmd'], ['xxx']],
|
||||||
\ 'sessionoptions': [['', 'blank', 'curdir', 'sesdir',
|
\ 'sessionoptions': [['', 'blank', 'curdir', 'sesdir',
|
||||||
|
@ -10,24 +10,25 @@ if exists('s:did_load')
|
|||||||
set formatoptions=tcq
|
set formatoptions=tcq
|
||||||
set fsync
|
set fsync
|
||||||
set include=^\\s*#\\s*include
|
set include=^\\s*#\\s*include
|
||||||
set laststatus=1
|
|
||||||
set listchars=eol:$
|
|
||||||
set joinspaces
|
set joinspaces
|
||||||
set jumpoptions=
|
set jumpoptions=
|
||||||
|
set laststatus=1
|
||||||
|
set listchars=eol:$
|
||||||
|
set maxsearchcount=99
|
||||||
set mousemodel=extend
|
set mousemodel=extend
|
||||||
set nohidden nosmarttab noautoindent noautoread noruler noshowcmd
|
set nohidden nosmarttab noautoindent noautoread noruler noshowcmd
|
||||||
set nohlsearch noincsearch
|
set nohlsearch noincsearch
|
||||||
set nrformats=bin,octal,hex
|
set nrformats=bin,octal,hex
|
||||||
set shortmess=filnxtToOS
|
set sessionoptions+=options
|
||||||
set shelltemp
|
set shelltemp
|
||||||
|
set shortmess=filnxtToOS
|
||||||
set sidescroll=0
|
set sidescroll=0
|
||||||
|
set startofline
|
||||||
|
set switchbuf=
|
||||||
set tags=./tags,tags
|
set tags=./tags,tags
|
||||||
set undodir^=.
|
set undodir^=.
|
||||||
set wildoptions=
|
|
||||||
set startofline
|
|
||||||
set sessionoptions+=options
|
|
||||||
set viewoptions+=options
|
set viewoptions+=options
|
||||||
set switchbuf=
|
set wildoptions=
|
||||||
if has('win32')
|
if has('win32')
|
||||||
set isfname+=:
|
set isfname+=:
|
||||||
endif
|
endif
|
||||||
|
@ -16,27 +16,27 @@ func Test_search_stat()
|
|||||||
" but setting @/ should also work (even 'n' nor 'N' was executed)
|
" but setting @/ should also work (even 'n' nor 'N' was executed)
|
||||||
" recompute the count when the last position is different.
|
" recompute the count when the last position is different.
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 40, incomplete: 0, maxcount: 999},
|
\ #{current: 1, exact_match: 1, total: 40, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'foo'}))
|
\ searchcount(#{pattern: 'foo'}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar'}))
|
\ searchcount(#{pattern: 'fooooobar'}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 0, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar', pos: [2, 1, 0]}))
|
\ searchcount(#{pattern: 'fooooobar', pos: [2, 1, 0]}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 1, 0]}))
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 1, 0]}))
|
||||||
" on last char of match
|
" on last char of match
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 1, exact_match: 1, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 9, 0]}))
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 9, 0]}))
|
||||||
" on char after match
|
" on char after match
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar', pos: [3, 10, 0]}))
|
\ searchcount(#{pattern: 'fooooobar', pos: [3, 10, 0]}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 999},
|
\ #{current: 1, exact_match: 0, total: 10, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0]}))
|
\ searchcount(#{pattern: 'fooooobar', pos: [4, 1, 0]}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 0, total: 2, incomplete: 2, maxcount: 1},
|
\ #{current: 1, exact_match: 0, total: 2, incomplete: 2, maxcount: 1},
|
||||||
@ -53,7 +53,7 @@ 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)
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 999},
|
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{recompute: 0}))
|
\ searchcount(#{recompute: 0}))
|
||||||
" didn't get added to message history
|
" didn't get added to message history
|
||||||
call assert_equal(messages_before, execute('messages'))
|
call assert_equal(messages_before, execute('messages'))
|
||||||
@ -64,7 +64,7 @@ func Test_search_stat()
|
|||||||
let stat = '\[50/50\]'
|
let stat = '\[50/50\]'
|
||||||
call assert_match(pat .. stat, g:a)
|
call assert_match(pat .. stat, g:a)
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 999},
|
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{recompute: 0}))
|
\ searchcount(#{recompute: 0}))
|
||||||
|
|
||||||
" No search stat
|
" No search stat
|
||||||
@ -75,65 +75,53 @@ func Test_search_stat()
|
|||||||
call assert_notmatch(pat .. stat, g:a)
|
call assert_notmatch(pat .. stat, g:a)
|
||||||
" n does not update search stat
|
" n does not update search stat
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 999},
|
\ #{current: 50, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{recompute: 0}))
|
\ searchcount(#{recompute: 0}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 999},
|
\ #{current: 2, exact_match: 1, total: 50, incomplete: 0, maxcount: 99},
|
||||||
\ searchcount(#{recompute: v:true}))
|
\ searchcount(#{recompute: v:true}))
|
||||||
set shortmess-=S
|
set shortmess-=S
|
||||||
|
|
||||||
" Nvim: max search count is 999; append more lines to surpass it.
|
|
||||||
" Create a new undo block so we can revert the change later.
|
|
||||||
" Also allow "[?/??]" in case of timeouts from the increased max, but set a
|
|
||||||
" larger timeout for the recomputing searchcount()s.
|
|
||||||
let &l:undolevels = &l:undolevels
|
|
||||||
call append(0, repeat(['foobar', 'foo', 'fooooobar', 'foba', 'foobar'], 99))
|
|
||||||
|
|
||||||
" Many matches
|
" Many matches
|
||||||
call cursor(line('$')-2, 1)
|
call cursor(line('$')-2, 1)
|
||||||
let @/ = '.'
|
let @/ = '.'
|
||||||
let pat = escape(@/, '()*?'). '\s\+'
|
let pat = escape(@/, '()*?'). '\s\+'
|
||||||
let g:a = execute(':unsilent :norm! n')
|
let g:a = execute(':unsilent :norm! n')
|
||||||
let stat = '\[\%(>999/>999\|?/??\)\]'
|
let stat = '\[>99/>99\]'
|
||||||
call assert_match(pat .. stat, g:a)
|
call assert_match(pat .. stat, g:a)
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1000, exact_match: 0, total: 1000, incomplete: 2, maxcount: 999},
|
\ #{current: 100, exact_match: 0, total: 100, incomplete: 2, maxcount: 99},
|
||||||
"\ Nvim: must recompute if the previous search timed out.
|
\ searchcount(#{recompute: 0}))
|
||||||
\ searchcount(#{recompute: (g:a =~# pat .. '\[?/??\]'), timeout: 500}))
|
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 3044, exact_match: 1, total: 3052, incomplete: 0, maxcount: 0},
|
\ #{current: 272, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
||||||
\ searchcount(#{recompute: v:true, maxcount: 0, timeout: 500}))
|
\ searchcount(#{recompute: v:true, maxcount: 0, timeout: 200}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 3052, incomplete: 0, maxcount: 0},
|
\ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
||||||
\ searchcount(#{recompute: 1, maxcount: 0, pos: [1, 1, 0], timeout: 500}))
|
\ searchcount(#{recompute: 1, maxcount: 0, pos: [1, 1, 0], timeout: 200}))
|
||||||
call cursor(line('$'), 1)
|
call cursor(line('$'), 1)
|
||||||
let g:a = execute(':unsilent :norm! n')
|
let g:a = execute(':unsilent :norm! n')
|
||||||
let stat = 'W \[\%(1/>999\|?/??\)\]'
|
let stat = 'W \[1/>99\]'
|
||||||
call assert_match(pat .. stat, g:a)
|
call assert_match(pat .. stat, g:a)
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 1000, incomplete: 2, maxcount: 999},
|
\ #{current: 1, exact_match: 1, total: 100, incomplete: 2, maxcount: 99},
|
||||||
"\ Nvim: must recompute if the previous search timed out.
|
\ searchcount(#{recompute: 0}))
|
||||||
\ searchcount(#{recompute: (g:a =~# pat .. '\[?/??\]'), timeout: 500}))
|
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 1, exact_match: 1, total: 3052, incomplete: 0, maxcount: 0},
|
\ #{current: 1, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
||||||
\ searchcount(#{recompute: 1, maxcount: 0, timeout: 500}))
|
\ searchcount(#{recompute: 1, maxcount: 0, timeout: 200}))
|
||||||
call assert_equal(
|
call assert_equal(
|
||||||
\ #{current: 3043, exact_match: 1, total: 3052, incomplete: 0, maxcount: 0},
|
\ #{current: 271, exact_match: 1, total: 280, incomplete: 0, maxcount: 0},
|
||||||
\ searchcount(#{recompute: 1, maxcount: 0, pos: [line('$')-2, 1, 0], timeout: 500}))
|
\ searchcount(#{recompute: 1, maxcount: 0, pos: [line('$')-2, 1, 0], timeout: 200}))
|
||||||
|
|
||||||
" 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/>999\|?/??\)\]'
|
let stat = '\[2/>99\]'
|
||||||
call assert_match(pat .. stat, g:a)
|
call assert_match(pat .. stat, g:a)
|
||||||
call cursor(1, 1)
|
call cursor(1, 1)
|
||||||
let g:a = execute(':unsilent :norm! N')
|
let g:a = execute(':unsilent :norm! N')
|
||||||
let stat = 'W \[\%(>999/>999\|?/??\)\]'
|
let stat = 'W \[>99/>99\]'
|
||||||
call assert_match(pat .. stat, g:a)
|
call assert_match(pat .. stat, g:a)
|
||||||
|
|
||||||
" Nvim: undo the extra lines.
|
|
||||||
undo
|
|
||||||
|
|
||||||
" right-left
|
" right-left
|
||||||
if exists("+rightleft")
|
if exists("+rightleft")
|
||||||
set rl
|
set rl
|
||||||
@ -490,4 +478,166 @@ func Test_search_stat_smartcase_ignorecase()
|
|||||||
call StopVimInTerminal(buf)
|
call StopVimInTerminal(buf)
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Reference in New Issue
Block a user