Merge pull request #12905 from janlazo/vim-8.1.0555

vim-patch:8.1.{499,555,556,584,640,1148,1704},8.2.0902
This commit is contained in:
Jan Edmund Lazo
2020-09-13 12:46:32 -04:00
committed by GitHub
9 changed files with 182 additions and 46 deletions

View File

@@ -2228,17 +2228,19 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only)
continue;
case 't': if (checkforcmd(&p, "tab", 3)) {
long tabnr = get_address(
eap, &eap->cmd, ADDR_TABS, eap->skip, skip_only, false, 1);
if (!skip_only) {
long tabnr = get_address(
eap, &eap->cmd, ADDR_TABS, eap->skip, skip_only, false, 1);
if (tabnr == MAXLNUM) {
cmdmod.tab = tabpage_index(curtab) + 1;
} else {
if (tabnr < 0 || tabnr > LAST_TAB_NR) {
*errormsg = (char_u *)_(e_invrange);
return false;
if (tabnr == MAXLNUM) {
cmdmod.tab = tabpage_index(curtab) + 1;
} else {
if (tabnr < 0 || tabnr > LAST_TAB_NR) {
*errormsg = (char_u *)_(e_invrange);
return false;
}
cmdmod.tab = tabnr + 1;
}
cmdmod.tab = tabnr + 1;
}
eap->cmd = p;
continue;

View File

@@ -276,6 +276,7 @@ static void init_incsearch_state(incsearch_state_T *s)
// Sets search_first_line and search_last_line to the address range.
static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s,
int *skiplen, int *patlen)
FUNC_ATTR_NONNULL_ALL
{
char_u *cmd;
cmdmod_T save_cmdmod = cmdmod;
@@ -443,6 +444,10 @@ static void may_do_incsearch_highlighting(int firstc, long count,
if (search_first_line == 0) {
// start at the original cursor position
curwin->w_cursor = s->search_start;
} else if (search_first_line > curbuf->b_ml.ml_line_count) {
// start after the last line
curwin->w_cursor.lnum = curbuf->b_ml.ml_line_count;
curwin->w_cursor.col = MAXCOL;
} else {
// start at the first line in the range
curwin->w_cursor.lnum = search_first_line;
@@ -563,6 +568,7 @@ static void may_do_incsearch_highlighting(int firstc, long count,
// May set "*c" to the added character.
// Return OK when calling command_line_not_changed.
static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
FUNC_ATTR_NONNULL_ALL
{
int skiplen, patlen;
@@ -579,8 +585,8 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
if (s->did_incsearch) {
curwin->w_cursor = s->match_end;
if (!equalpos(curwin->w_cursor, s->search_start)) {
*c = gchar_cursor();
*c = gchar_cursor();
if (*c != NUL) {
// If 'ignorecase' and 'smartcase' are set and the
// command line has no uppercase characters, convert
// the character to lowercase
@@ -588,16 +594,14 @@ static int may_add_char_to_search(int firstc, int *c, incsearch_state_T *s)
&& !pat_has_uppercase(ccline.cmdbuff + skiplen)) {
*c = mb_tolower(*c);
}
if (*c != NUL) {
if (*c == firstc
|| vim_strchr((char_u *)(p_magic ? "\\~^$.*[" : "\\^$"), *c)
!= NULL) {
// put a backslash before special characters
stuffcharReadbuff(*c);
*c = '\\';
}
return FAIL;
if (*c == firstc
|| vim_strchr((char_u *)(p_magic ? "\\~^$.*[" : "\\^$"), *c)
!= NULL) {
// put a backslash before special characters
stuffcharReadbuff(*c);
*c = '\\';
}
return FAIL;
}
}
return OK;
@@ -1444,6 +1448,7 @@ static int command_line_execute(VimState *state, int key)
static int may_do_command_line_next_incsearch(int firstc, long count,
incsearch_state_T *s,
bool next_match)
FUNC_ATTR_NONNULL_ALL
{
int skiplen, patlen;
@@ -1537,6 +1542,7 @@ static int may_do_command_line_next_incsearch(int firstc, long count,
save_viewstate(&s->old_viewstate);
update_screen(NOT_VALID);
redrawcmdline();
curwin->w_cursor = s->match_end;
} else {
vim_beep(BO_ERROR);
}

View File

@@ -1818,6 +1818,7 @@ ml_get_buf (
linenr_T lnum,
bool will_change // line will be changed
)
FUNC_ATTR_NONNULL_ALL
{
bhdr_T *hp;
DATA_BL *dp;

View File

@@ -901,6 +901,7 @@ static bool qf_list_has_valid_entries(qf_list_T *qfl)
/// Return a pointer to a list in the specified quickfix stack
static qf_list_T * qf_get_list(qf_info_T *qi, int idx)
FUNC_ATTR_NONNULL_ALL
{
return &qi->qf_lists[idx];
}
@@ -1230,6 +1231,7 @@ static char_u * qf_cmdtitle(char_u *cmd)
/// Return a pointer to the current list in the specified quickfix stack
static qf_list_T * qf_get_curlist(qf_info_T *qi)
FUNC_ATTR_NONNULL_ALL
{
return qf_get_list(qi, qi->qf_curlist);
}
@@ -4825,12 +4827,13 @@ static bool vgr_qflist_valid(win_T *wp, qf_info_T *qi, unsigned qfid,
/// Search for a pattern in all the lines in a buffer and add the matching lines
/// to a quickfix list.
static bool vgr_match_buflines(qf_info_T *qi, char_u *fname, buf_T *buf,
regmmatch_T *regmatch, long tomatch,
regmmatch_T *regmatch, long *tomatch,
int duplicate_name, int flags)
FUNC_ATTR_NONNULL_ARG(1, 3, 4, 5)
{
bool found_match = false;
for (long lnum = 1; lnum <= buf->b_ml.ml_line_count && tomatch > 0; lnum++) {
for (long lnum = 1; lnum <= buf->b_ml.ml_line_count && *tomatch > 0; lnum++) {
colnr_T col = 0;
while (vim_regexec_multi(regmatch, curwin, buf, lnum, col, NULL,
NULL) > 0) {
@@ -4856,7 +4859,7 @@ static bool vgr_match_buflines(qf_info_T *qi, char_u *fname, buf_T *buf,
break;
}
found_match = true;
if (--tomatch == 0) {
if (--*tomatch == 0) {
break;
}
if ((flags & VGR_GLOBAL) == 0 || regmatch->endpos[0].lnum > 0) {
@@ -5030,7 +5033,7 @@ void ex_vimgrep(exarg_T *eap)
} else {
// Try for a match in all lines of the buffer.
// For ":1vimgrep" look for first match only.
found_match = vgr_match_buflines(qi, fname, buf, &regmatch, tomatch,
found_match = vgr_match_buflines(qi, fname, buf, &regmatch, &tomatch,
duplicate_name, flags);
if (using_dummy) {

View File

@@ -7387,6 +7387,7 @@ long vim_regexec_multi(
proftime_T *tm, // timeout limit or NULL
int *timed_out // flag is set when timeout limit reached
)
FUNC_ATTR_NONNULL_ARG(1)
{
regexec_T rex_save;
bool rex_in_use_save = rex_in_use;

View File

@@ -96,12 +96,8 @@ static int lastc_bytelen = 1; // >1 for multi-byte char
// copy of spats[], for keeping the search patterns while executing autocmds
static struct spat saved_spats[2];
// copy of spats[RE_SEARCH], for keeping the search patterns while incremental
// searching
static struct spat saved_last_search_spat;
static int did_save_last_search_spat = 0;
static int saved_last_idx = 0;
static bool saved_no_hlsearch = false;
static int saved_spats_last_idx = 0;
static bool saved_spats_no_hlsearch = false;
static char_u *mr_pattern = NULL; // pattern used by search_regcomp()
static int mr_pattern_alloced = false; // mr_pattern was allocated
@@ -268,8 +264,8 @@ void save_search_patterns(void)
saved_spats[1] = spats[1];
if (spats[1].pat != NULL)
saved_spats[1].pat = vim_strsave(spats[1].pat);
saved_last_idx = last_idx;
saved_no_hlsearch = no_hlsearch;
saved_spats_last_idx = last_idx;
saved_spats_no_hlsearch = no_hlsearch;
}
}
@@ -281,8 +277,8 @@ void restore_search_patterns(void)
set_vv_searchforward();
free_spat(&spats[1]);
spats[1] = saved_spats[1];
last_idx = saved_last_idx;
set_no_hlsearch(saved_no_hlsearch);
last_idx = saved_spats_last_idx;
set_no_hlsearch(saved_spats_no_hlsearch);
}
}
@@ -309,6 +305,13 @@ void free_search_patterns(void)
#endif
// copy of spats[RE_SEARCH], for keeping the search patterns while incremental
// searching
static struct spat saved_last_search_spat;
static int did_save_last_search_spat = 0;
static int saved_last_idx = 0;
static bool saved_no_hlsearch = false;
/// Save and restore the search pattern for incremental highlight search
/// feature.
///
@@ -317,10 +320,9 @@ void free_search_patterns(void)
/// cancelling incremental searching even if it's called inside user functions.
void save_last_search_pattern(void)
{
if (did_save_last_search_spat != 0) {
IEMSG("did_save_last_search_spat is not zero");
} else {
did_save_last_search_spat++;
if (++did_save_last_search_spat != 1) {
// nested call, nothing to do
return;
}
saved_last_search_spat = spats[RE_SEARCH];
@@ -333,11 +335,15 @@ void save_last_search_pattern(void)
void restore_last_search_pattern(void)
{
if (did_save_last_search_spat != 1) {
IEMSG("did_save_last_search_spat is not one");
if (--did_save_last_search_spat > 0) {
// nested call, nothing to do
return;
}
if (did_save_last_search_spat != 0) {
iemsg("restore_last_search_pattern() called more often than"
" save_last_search_pattern()");
return;
}
did_save_last_search_spat--;
xfree(spats[RE_SEARCH].pat);
spats[RE_SEARCH] = saved_last_search_spat;
@@ -488,7 +494,7 @@ void set_last_search_pat(const char_u *s, int idx, int magic, int setlast)
saved_spats[idx].pat = NULL;
else
saved_spats[idx].pat = vim_strsave(spats[idx].pat);
saved_last_idx = last_idx;
saved_spats_last_idx = last_idx;
}
/* If 'hlsearch' set and search pat changed: need redraw. */
if (p_hls && idx == last_idx && !no_hlsearch)
@@ -1179,7 +1185,7 @@ int do_search(
}
if (*searchstr == NUL) {
p = spats[last_idx].pat;
p = spats[0].pat;
} else {
p = searchstr;
}

View File

@@ -2450,6 +2450,22 @@ func Test_vimgrep()
call XvimgrepTests('l')
endfunc
" Test for incsearch highlighting of the :vimgrep pattern
" This test used to cause "E315: ml_get: invalid lnum" errors.
func Test_vimgrep_incsearch()
throw 'skipped: Nvim does not support test_override()'
enew
set incsearch
call test_override("char_avail", 1)
call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
let l = getqflist()
call assert_equal(2, len(l))
call test_override("ALL", 0)
set noincsearch
endfunc
func XfreeTests(cchar)
call s:setup_commands(a:cchar)

View File

@@ -244,6 +244,10 @@ func Test_search_cmdline2()
" go to previous match (on line 2)
call feedkeys("/the\<C-G>\<C-G>\<C-G>\<C-T>\<C-T>\<C-T>\<cr>", 'tx')
call assert_equal(' 2 these', getline('.'))
1
" go to previous match (on line 2)
call feedkeys("/the\<C-G>\<C-R>\<C-W>\<cr>", 'tx')
call assert_equal('theother', @/)
" Test 2: keep the view,
" after deleting a character from the search cmd
@@ -255,7 +259,7 @@ func Test_search_cmdline2()
call assert_equal({'lnum': 10, 'leftcol': 0, 'col': 4, 'topfill': 0, 'topline': 6, 'coladd': 0, 'skipcol': 0, 'curswant': 4}, winsaveview())
" remove all history entries
for i in range(10)
for i in range(11)
call histdel('/')
endfor
@@ -489,14 +493,14 @@ func Test_search_cmdline5()
" Do not call test_override("char_avail", 1) so that <C-g> and <C-t> work
" regardless char_avail.
new
call setline(1, [' 1 the first', ' 2 the second', ' 3 the third'])
call setline(1, [' 1 the first', ' 2 the second', ' 3 the third', ''])
set incsearch
1
call feedkeys("/the\<c-g>\<c-g>\<cr>", 'tx')
call assert_equal(' 3 the third', getline('.'))
$
call feedkeys("?the\<c-t>\<c-t>\<c-t>\<cr>", 'tx')
call assert_equal(' 2 the second', getline('.'))
call assert_equal(' 1 the first', getline('.'))
" clean up
set noincsearch
bw!
@@ -861,6 +865,21 @@ func Test_incsearch_with_change()
call delete('Xis_change_script')
endfunc
func Test_incsearch_cmdline_modifier()
throw 'skipped: Nvim does not support test_override()'
if !exists('+incsearch')
return
endif
call test_override("char_avail", 1)
new
call setline(1, ['foo'])
set incsearch
" Test that error E14 does not occur in parsing command modifier.
call feedkeys("V:tab", 'tx')
call Incsearch_cleanup()
endfunc
func Test_incsearch_scrolling()
if !CanRunVimInTerminal()
return
@@ -982,6 +1001,40 @@ func Test_search_sentence()
/
endfunc
" Test that there is no crash when there is a last search pattern but no last
" substitute pattern.
func Test_no_last_substitute_pat()
" Use viminfo to set the last search pattern to a string and make the last
" substitute pattern the most recent used and make it empty (NULL).
call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo')
rviminfo! Xviminfo
call assert_fails('normal n', 'E35:')
call delete('Xviminfo')
endfunc
func Test_search_Ctrl_L_combining()
" Make sure, that Ctrl-L works correctly with combining characters.
" It uses an artificial example of an 'a' with 4 combining chars:
" 'a' U+0061 Dec:97 LATIN SMALL LETTER A &#x61; /\%u61\Z "\u0061"
" ' ̀' U+0300 Dec:768 COMBINING GRAVE ACCENT &#x300; /\%u300\Z "\u0300"
" ' ́' U+0301 Dec:769 COMBINING ACUTE ACCENT &#x301; /\%u301\Z "\u0301"
" ' ̇' U+0307 Dec:775 COMBINING DOT ABOVE &#x307; /\%u307\Z "\u0307"
" ' ̣' U+0323 Dec:803 COMBINING DOT BELOW &#x323; /\%u323 "\u0323"
" Those should also appear on the commandline
if !has('multi_byte') || !exists('+incsearch')
return
endif
call Cmdline3_prep()
1
let bufcontent = ['', 'Miạ̀́̇m']
call append('$', bufcontent)
call feedkeys("/Mi\<c-l>\<c-l>\<cr>", 'tx')
call assert_equal(5, line('.'))
call assert_equal(bufcontent[1], @/)
call Incsearch_cleanup()
endfunc
func Test_large_hex_chars1()
" This used to cause a crash, the character becomes an NFA state.
try
@@ -1019,6 +1072,24 @@ func Test_one_error_msg()
call assert_fails('call search(" \\((\\v[[=P=]]){185}+ ")', 'E871:')
endfunc
func Test_incsearch_add_char_under_cursor()
throw 'skipped: Nvim does not support test_override()'
if !exists('+incsearch')
return
endif
set incsearch
new
call setline(1, ['find match', 'anything'])
1
call test_override('char_avail', 1)
call feedkeys("fc/m\<C-L>\<C-L>\<C-L>\<C-L>\<C-L>\<CR>", 'tx')
call assert_equal('match', @/)
call test_override('char_avail', 0)
set incsearch&
bwipe!
endfunc
" Test for the search() function with match at the cursor position
func Test_search_match_at_curpos()
new

View File

@@ -4,6 +4,8 @@
" as test!
source shared.vim
source screendump.vim
source check.vim
func! Test_search_stat()
new
@@ -164,3 +166,31 @@ func! Test_search_stat()
set shortmess+=S
bwipe!
endfunc
func Test_searchcount_in_statusline()
CheckScreendump
let lines =<< trim END
set shortmess-=S
call append(0, 'this is something')
function TestSearchCount() abort
let search_count = searchcount()
if !empty(search_count)
return '[' . search_count.current . '/' . search_count.total . ']'
else
return ''
endif
endfunction
set hlsearch
set laststatus=2 statusline+=%{TestSearchCount()}
END
call writefile(lines, 'Xsearchstatusline')
let buf = RunVimInTerminal('-S Xsearchstatusline', #{rows: 10})
call TermWait(buf)
call term_sendkeys(buf, "/something")
call VerifyScreenDump(buf, 'Test_searchstat_4', {})
call term_sendkeys(buf, "\<Esc>")
call StopVimInTerminal(buf)
call delete('Xsearchstatusline')
endfunc