# HG changeset patch # User Bram Moolenaar # Date 1567711803 -7200 # Node ID 2ea47dee7ddd945e3c8d32ba816c5843e4091e08 # Parent 9814aa081796c3e3e3c223d5d877752cb65e1962 patch 8.1.1988: :startinsert! does not work the same way as "A" Commit: https://github.com/vim/vim/commit/8d3b51084a5bdcd2ee9e31bc03cba0d16c43d428 Author: Bram Moolenaar Date: Thu Sep 5 21:29:01 2019 +0200 patch 8.1.1988: :startinsert! does not work the same way as "A" Problem: :startinsert! does not work the same way as "A". Solution: Use the same code to move the cursor. (closes https://github.com/vim/vim/issues/4896) diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7596,16 +7596,14 @@ ex_startinsert(exarg_T *eap) { if (eap->forceit) { - /* cursor line can be zero on startup */ + // cursor line can be zero on startup if (!curwin->w_cursor.lnum) curwin->w_cursor.lnum = 1; - coladvance((colnr_T)MAXCOL); - curwin->w_curswant = MAXCOL; - curwin->w_set_curswant = FALSE; - } - - /* Ignore the command when already in Insert mode. Inserting an - * expression register that invokes a function can do this. */ + set_cursor_for_append_to_line(); + } + + // Ignore the command when already in Insert mode. Inserting an + // expression register that invokes a function can do this. if (State & INSERT) return; @@ -7620,7 +7618,7 @@ ex_startinsert(exarg_T *eap) { if (eap->cmdidx == CMD_startinsert) restart_edit = 'i'; - curwin->w_curswant = 0; /* avoid MAXCOL */ + curwin->w_curswant = 0; // avoid MAXCOL } } diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -8898,6 +8898,27 @@ nv_esc(cmdarg_T *cap) } /* + * Move the cursor for the "A" command. + */ + void +set_cursor_for_append_to_line(void) +{ + curwin->w_set_curswant = TRUE; + if (ve_flags == VE_ALL) + { + int save_State = State; + + /* Pretend Insert mode here to allow the cursor on the + * character past the end of the line */ + State = INSERT; + coladvance((colnr_T)MAXCOL); + State = save_State; + } + else + curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor()); +} + +/* * Handle "A", "a", "I", "i" and commands. * Also handle K_PS, start bracketed paste. */ @@ -8983,19 +9004,7 @@ nv_edit(cmdarg_T *cap) switch (cap->cmdchar) { case 'A': /* "A"ppend after the line */ - curwin->w_set_curswant = TRUE; - if (ve_flags == VE_ALL) - { - int save_State = State; - - /* Pretend Insert mode here to allow the cursor on the - * character past the end of the line */ - State = INSERT; - coladvance((colnr_T)MAXCOL); - State = save_State; - } - else - curwin->w_cursor.col += (colnr_T)STRLEN(ml_get_cursor()); + set_cursor_for_append_to_line(); break; case 'I': /* "I"nsert before the first non-blank */ diff --git a/src/proto/normal.pro b/src/proto/normal.pro --- a/src/proto/normal.pro +++ b/src/proto/normal.pro @@ -23,4 +23,5 @@ void do_nv_ident(int c1, int c2); int get_visual_text(cmdarg_T *cap, char_u **pp, int *lenp); void start_selection(void); void may_start_select(int c); +void set_cursor_for_append_to_line(void); /* vim: set ft=c : */ diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim --- a/src/testdir/test_edit.vim +++ b/src/testdir/test_edit.vim @@ -1480,3 +1480,18 @@ func Test_edit_special_chars() close! endfunc + +func Test_edit_startinsert() + new + set backspace+=start + call setline(1, 'foobar') + call feedkeys("A\\", 'xt') + call assert_equal('', getline(1)) + + call setline(1, 'foobar') + call feedkeys(":startinsert!\\\", 'xt') + call assert_equal('', getline(1)) + + set backspace& + bwipe! +endfunc diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -758,6 +758,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1988, +/**/ 1987, /**/ 1986,