diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak index c2e808c954..65da331b73 100644 --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -289,7 +289,8 @@ MSVC_MAJOR = ($(MSVCVER) / 100 - 6) MSVCRT_VER = ($(MSVCVER) / 10 - 60) # Visual C++ 2017 needs special handling # it has an _MSC_VER of 1910->14.1, but is actually v15 with runtime v140 -!elseif $(MSVCVER) == 1910 +# TODO: what's the maximum value? +!elseif $(MSVCVER) >= 1910 MSVC_MAJOR = 15 MSVCRT_VER = 140 !else diff --git a/src/normal.c b/src/normal.c index c74f48f445..82fe768d05 100644 --- a/src/normal.c +++ b/src/normal.c @@ -1685,11 +1685,19 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank) get_op_char(oap->op_type), get_extra_op_char(oap->op_type), oap->motion_force, cap->cmdchar, cap->nchar); else if (cap->cmdchar != ':') + { + int nchar = oap->op_type == OP_REPLACE ? cap->nchar : NUL; + + /* reverse what nv_replace() did */ + if (nchar == REPLACE_CR_NCHAR) + nchar = CAR; + else if (nchar == REPLACE_NL_NCHAR) + nchar = NL; prep_redo(oap->regname, 0L, NUL, 'v', get_op_char(oap->op_type), get_extra_op_char(oap->op_type), - oap->op_type == OP_REPLACE - ? cap->nchar : NUL); + nchar); + } if (!redo_VIsual_busy) { redo_VIsual_mode = resel_VIsual_mode; @@ -7057,10 +7065,12 @@ nv_replace(cmdarg_T *cap) reset_VIsual(); if (had_ctrl_v) { - if (cap->nchar == '\r') - cap->nchar = -1; - else if (cap->nchar == '\n') - cap->nchar = -2; + /* Use a special (negative) number to make a difference between a + * literal CR or NL and a line break. */ + if (cap->nchar == CAR) + cap->nchar = REPLACE_CR_NCHAR; + else if (cap->nchar == NL) + cap->nchar = REPLACE_NL_NCHAR; } nv_operator(cap); return; diff --git a/src/ops.c b/src/ops.c index 83c36bda67..1350d82641 100644 --- a/src/ops.c +++ b/src/ops.c @@ -2113,13 +2113,21 @@ op_replace(oparg_T *oap, int c) size_t oldlen; struct block_def bd; char_u *after_p = NULL; - int had_ctrl_v_cr = (c == -1 || c == -2); + int had_ctrl_v_cr = FALSE; if ((curbuf->b_ml.ml_flags & ML_EMPTY ) || oap->empty) return OK; /* nothing to do */ - if (had_ctrl_v_cr) - c = (c == -1 ? '\r' : '\n'); + if (c == REPLACE_CR_NCHAR) + { + had_ctrl_v_cr = TRUE; + c = CAR; + } + else if (c == REPLACE_NL_NCHAR) + { + had_ctrl_v_cr = TRUE; + c = NL; + } #ifdef FEAT_MBYTE if (has_mbyte) @@ -2207,7 +2215,8 @@ op_replace(oparg_T *oap, int c) /* insert pre-spaces */ vim_memset(newp + bd.textcol, ' ', (size_t)bd.startspaces); /* insert replacement chars CHECK FOR ALLOCATED SPACE */ - /* -1/-2 is used for entering CR literally. */ + /* REPLACE_CR_NCHAR/REPLACE_NL_NCHAR is used for entering CR + * literally. */ if (had_ctrl_v_cr || (c != '\r' && c != '\n')) { #ifdef FEAT_MBYTE @@ -6370,7 +6379,7 @@ write_viminfo_registers(FILE *fp) * |{bartype},{flags},{name},{type}, * {linecount},{width},{timestamp},"line1","line2" * flags: REG_PREVIOUS - register is y_previous - * REG_EXEC - used for @@ + * REG_EXEC - used for @@ */ if (y_previous == &y_regs[i]) flags |= REG_PREVIOUS; diff --git a/src/testdir/test_undo.vim b/src/testdir/test_undo.vim index cc3cceb1ae..c1b821e4e1 100644 --- a/src/testdir/test_undo.vim +++ b/src/testdir/test_undo.vim @@ -403,3 +403,10 @@ func Test_undo_0() bwipe! endfunc + +func Test_redo_empty_line() + new + exe "norm\x16r\x160" + exe "norm." + bwipe! +endfunc diff --git a/src/version.c b/src/version.c index e8d43c2a47..ab7b568acf 100644 --- a/src/version.c +++ b/src/version.c @@ -786,6 +786,10 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 1475, +/**/ + 1474, /**/ 1473, /**/ diff --git a/src/vim.h b/src/vim.h index eb5d3a10bf..0a9d50f630 100644 --- a/src/vim.h +++ b/src/vim.h @@ -2517,4 +2517,8 @@ typedef enum { # endif #endif +/* Replacement for nchar used by nv_replace(). */ +#define REPLACE_CR_NCHAR -1 +#define REPLACE_NL_NCHAR -2 + #endif /* VIM__H */