Merge remote-tracking branch 'upstream/master'

This commit is contained in:
ckelsel 2017-09-17 20:41:47 +08:00
commit 6258e33b11
5 changed files with 93 additions and 36 deletions

4
BSDmakefile Normal file
View File

@ -0,0 +1,4 @@
.DONE:
@echo "Please use GNU Make (gmake) to build neovim"
.DEFAULT:
@echo "Please use GNU Make (gmake) to build neovim"

View File

@ -3665,6 +3665,42 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
* use "\=col("."). */ * use "\=col("."). */
curwin->w_cursor.col = regmatch.startpos[0].col; curwin->w_cursor.col = regmatch.startpos[0].col;
// When the match included the "$" of the last line it may
// go beyond the last line of the buffer.
if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) {
nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
skip_match = true;
}
#define ADJUST_SUB_FIRSTLNUM() \
do { \
/* For a multi-line match, make a copy of the last matched */ \
/* line and continue in that one. */ \
if (nmatch > 1) { \
sub_firstlnum += nmatch - 1; \
xfree(sub_firstline); \
sub_firstline = vim_strsave(ml_get(sub_firstlnum)); \
/* When going beyond the last line, stop substituting. */ \
if (sub_firstlnum <= line2) { \
do_again = true; \
} else { \
subflags.do_all = false; \
} \
} \
if (skip_match) { \
/* Already hit end of the buffer, sub_firstlnum is one */ \
/* less than what it ought to be. */ \
xfree(sub_firstline); \
sub_firstline = vim_strsave((char_u *)""); \
copycol = 0; \
} \
} while (0)
if (preview && !has_second_delim) {
ADJUST_SUB_FIRSTLNUM();
goto skip;
}
// 3. Substitute the string. During 'inccommand' preview only do this if // 3. Substitute the string. During 'inccommand' preview only do this if
// there is a replace pattern. // there is a replace pattern.
if (!preview || has_second_delim) { if (!preview || has_second_delim) {
@ -3691,13 +3727,6 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
goto skip; goto skip;
} }
// When the match included the "$" of the last line it may
// go beyond the last line of the buffer.
if (nmatch > curbuf->b_ml.ml_line_count - sub_firstlnum + 1) {
nmatch = curbuf->b_ml.ml_line_count - sub_firstlnum + 1;
skip_match = true;
}
// Need room for: // Need room for:
// - result so far in new_start (not for first sub in line) // - result so far in new_start (not for first sub in line)
// - original text up to match // - original text up to match
@ -3728,30 +3757,10 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout)
// is beyond the end of the line after the substitution. // is beyond the end of the line after the substitution.
curwin->w_cursor.col = 0; curwin->w_cursor.col = 0;
// For a multi-line match, make a copy of the last matched
// line and continue in that one.
if (nmatch > 1) {
sub_firstlnum += nmatch - 1;
xfree(sub_firstline);
sub_firstline = vim_strsave(ml_get(sub_firstlnum));
// When going beyond the last line, stop substituting.
if (sub_firstlnum <= line2) {
do_again = true;
} else {
subflags.do_all = false;
}
}
// Remember next character to be copied. // Remember next character to be copied.
copycol = regmatch.endpos[0].col; copycol = regmatch.endpos[0].col;
if (skip_match) { ADJUST_SUB_FIRSTLNUM();
// Already hit end of the buffer, sub_firstlnum is one
// less than what it ought to be.
xfree(sub_firstline);
sub_firstline = vim_strsave((char_u *)"");
copycol = 0;
}
// Now the trick is to replace CTRL-M chars with a real line // Now the trick is to replace CTRL-M chars with a real line
// break. This would make it impossible to insert a CTRL-M in // break. This would make it impossible to insert a CTRL-M in
@ -4008,6 +4017,7 @@ skip:
kv_destroy(matched_lines); kv_destroy(matched_lines);
return preview_buf; return preview_buf;
#undef ADJUST_SUB_FIRSTLNUM
} // NOLINT(readability/fn_size) } // NOLINT(readability/fn_size)
/* /*

View File

@ -92,17 +92,15 @@ static int typeahead_char = 0; /* typeahead char that's not flushed */
*/ */
static int block_redo = FALSE; static int block_redo = FALSE;
/* // Make a hash value for a mapping.
* Make a hash value for a mapping. // "mode" is the lower 4 bits of the State for the mapping.
* "mode" is the lower 4 bits of the State for the mapping. // "c1" is the first character of the "lhs".
* "c1" is the first character of the "lhs". // Returns a value between 0 and 255, index in maphash.
* Returns a value between 0 and 255, index in maphash. // Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
* Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode.
*/
#define MAP_HASH(mode, \ #define MAP_HASH(mode, \
c1) (((mode) & \ c1) (((mode) & \
(NORMAL + VISUAL + SELECTMODE + \ (NORMAL + VISUAL + SELECTMODE + \
OP_PENDING)) ? (c1) : ((c1) ^ 0x80)) OP_PENDING + TERM_FOCUS)) ? (c1) : ((c1) ^ 0x80))
// Each mapping is put in one of the MAX_MAPHASH hash lists, // Each mapping is put in one of the MAX_MAPHASH hash lists,
// to speed up finding it. // to speed up finding it.

View File

@ -364,6 +364,24 @@ describe('api', function()
first line first line
second line]]) second line]])
end) end)
it('does not complete ("interrupt") `d` #3732', function()
local screen = Screen.new(20, 4)
screen:attach()
command('set listchars=eol:$')
command('set list')
feed('ia<cr>b<cr>c<cr><Esc>kkk')
feed('d')
-- Make any RPC request (can be non-async: op-pending does not block).
nvim('get_current_buf')
screen:expect([[
^a$ |
b$ |
c$ |
|
]])
end)
it('does not complete ("interrupt") normal-mode map-pending', function() it('does not complete ("interrupt") normal-mode map-pending', function()
command("nnoremap dd :let g:foo='it worked...'<CR>") command("nnoremap dd :let g:foo='it worked...'<CR>")
helpers.insert([[ helpers.insert([[

View File

@ -14,6 +14,7 @@ local neq = helpers.neq
local ok = helpers.ok local ok = helpers.ok
local source = helpers.source local source = helpers.source
local wait = helpers.wait local wait = helpers.wait
local nvim = helpers.nvim
local default_text = [[ local default_text = [[
Inc substitution on Inc substitution on
@ -1647,3 +1648,29 @@ describe("'inccommand' split windows", function()
end) end)
end) end)
describe("'inccommand' with 'gdefault'", function()
before_each(function()
clear()
end)
it("does not lock up #7244", function()
common_setup(nil, "nosplit", "{")
command("set gdefault")
feed(":s/{\\n")
eq({mode='c', blocking=false}, nvim("get_mode"))
feed("/A<Enter>")
expect("A")
eq({mode='n', blocking=false}, nvim("get_mode"))
end)
it("with multiline text and range, does not lock up #7244", function()
common_setup(nil, "nosplit", "{\n\n{")
command("set gdefault")
feed(":%s/{\\n")
eq({mode='c', blocking=false}, nvim("get_mode"))
feed("/A<Enter>")
expect("A\nA")
eq({mode='n', blocking=false}, nvim("get_mode"))
end)
end)