diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 85fd450a10..dd2354b14a 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2295,33 +2295,42 @@ static void stop_insert(pos_T *end_insert_pos, int esc, int nomove) curwin->w_cursor = *end_insert_pos; check_cursor_col(curwin); // make sure it is not past the line - while (true) { - if (gchar_cursor() == NUL && curwin->w_cursor.col > 0) { - curwin->w_cursor.col--; - } - cc = gchar_cursor(); - if (!ascii_iswhite(cc)) { - break; - } - if (del_char(true) == FAIL) { - break; // should not happen - } - } - if (curwin->w_cursor.lnum != tpos.lnum) { - curwin->w_cursor = tpos; - } else if (curwin->w_cursor.col < prev_col) { - // reset tpos, could have been invalidated in the loop above - tpos = curwin->w_cursor; - tpos.col++; - if (cc != NUL && gchar_pos(&tpos) == NUL) { - curwin->w_cursor.col++; // put cursor back on the NUL - } + + // Where the loop would actually start (back up if NUL). + colnr_T strip_col = curwin->w_cursor.col; + if (gchar_cursor() == NUL && strip_col > 0) { + strip_col--; } - // may have started Visual mode, adjust the position for - // deleted characters. - if (VIsual_active) { - check_visual_pos(); + // Don't strip if non-whitespace follows: setline() from a + // mapping or CursorHoldI autocmd may have inserted content. + if (*skipwhite(get_cursor_line_ptr() + strip_col) == NUL) { + curwin->w_cursor.col = strip_col; + while (true) { + cc = gchar_cursor(); + if (!ascii_iswhite(cc)) { + break; + } + if (del_char(true) == FAIL) { + break; // should not happen + } + } + if (curwin->w_cursor.lnum != tpos.lnum) { + curwin->w_cursor = tpos; + } else if (curwin->w_cursor.col < prev_col) { + // reset tpos, could have been invalidated in the loop above + tpos = curwin->w_cursor; + tpos.col++; + if (cc != NUL && gchar_pos(&tpos) == NUL) { + curwin->w_cursor.col++; // put cursor back on the NUL + } + } + + // may have started Visual mode, adjust the position for + // deleted characters. + if (VIsual_active) { + check_visual_pos(); + } } } } diff --git a/test/old/testdir/test_edit.vim b/test/old/testdir/test_edit.vim index 7abae9c849..4530e2116f 100644 --- a/test/old/testdir/test_edit.vim +++ b/test/old/testdir/test_edit.vim @@ -2474,4 +2474,28 @@ func Test_edit_CAR_with_completion() bw! endfunc +func Test_autoindent_no_strip_after_cmd_setline() + new + setlocal autoindent + inoremap call setline('.', 'v v')call cursor(line('.'), 2) + call feedkeys("Go\\", 'tx') + call assert_equal('v v', getline(2)) + bwipe! +endfunc + +func Test_autoindent_no_strip_after_cursorholdi() + CheckFeature timers + new + setlocal autoindent + set updatetime=50 + au CursorHoldI call setline('.', 'v v') + call setline(1, ' x') + call cursor(1, 2) + call timer_start(120, {-> feedkeys("\", 't')}) + call feedkeys("o", 'tx!') + call assert_equal('v v', getline(2)) + set updatetime& + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab