# HG changeset patch # User Bram Moolenaar # Date 1553637606 -3600 # Node ID 5c5d211bd5a80238ac792c719ca532f75ddcfcd0 # Parent 1c8969addd04d8216b33b1521597930e819353fe patch 8.1.1055: CTRL-G U in Insert mode doesn't work for shift-Left commit https://github.com/vim/vim/commit/75bf3d22f42684beecd977f3185e98045b5c33d9 Author: Bram Moolenaar Date: Tue Mar 26 22:46:05 2019 +0100 patch 8.1.1055: CTRL-G U in Insert mode doesn't work for shift-Left Problem: CTRL-G U in Insert mode doesn't work to avoid splitting the undo sequence for shift-left and shift-right. Solution: Also check dont_sync_undo for shifted cursor keys. (Christian Brabandt) diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -236,11 +236,11 @@ static void ins_mousescroll(int dir); #if defined(FEAT_GUI_TABLINE) || defined(PROTO) static void ins_tabline(int c); #endif -static void ins_left(int end_change); +static void ins_left(void); static void ins_home(int c); static void ins_end(int c); static void ins_s_left(void); -static void ins_right(int end_change); +static void ins_right(void); static void ins_s_right(void); static void ins_up(int startcol); static void ins_pageup(void); @@ -290,10 +290,10 @@ static int ins_need_undo; /* call u_sav char. Set when edit() is called. after that arrow_used is used. */ -static int did_add_space = FALSE; /* auto_format() added an extra space - under the cursor */ -static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for - the next left/right cursor */ +static int did_add_space = FALSE; // auto_format() added an extra space + // under the cursor +static int dont_sync_undo = FALSE; // CTRL-G U prevents syncing undo for + // the next left/right cursor key /* * edit(): Start inserting text. @@ -1284,7 +1284,7 @@ doESCkey: if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) ins_s_left(); else - ins_left(dont_sync_undo == FALSE); + ins_left(); break; case K_S_LEFT: /* */ @@ -1296,7 +1296,7 @@ doESCkey: if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) ins_s_right(); else - ins_right(dont_sync_undo == FALSE); + ins_right(); break; case K_S_RIGHT: /* */ @@ -9291,10 +9291,10 @@ ins_horscroll(void) #endif static void -ins_left( - int end_change) /* end undoable change */ +ins_left(void) { pos_T tpos; + int end_change = dont_sync_undo == FALSE; // end undoable change #ifdef FEAT_FOLDING if ((fdo_flags & FDO_HOR) && KeyTyped) @@ -9378,8 +9378,9 @@ ins_end(int c) } static void -ins_s_left(void) -{ +ins_s_left() +{ + int end_change = dont_sync_undo == FALSE; // end undoable change #ifdef FEAT_FOLDING if ((fdo_flags & FDO_HOR) && KeyTyped) foldOpenCursor(); @@ -9387,18 +9388,22 @@ ins_s_left(void) undisplay_dollar(); if (curwin->w_cursor.lnum > 1 || curwin->w_cursor.col > 0) { - start_arrow(&curwin->w_cursor); + start_arrow_with_change(&curwin->w_cursor, end_change); + if (!end_change) + AppendCharToRedobuff(K_S_LEFT); (void)bck_word(1L, FALSE, FALSE); curwin->w_set_curswant = TRUE; } else vim_beep(BO_CRSR); + dont_sync_undo = FALSE; } static void -ins_right( - int end_change) /* end undoable change */ -{ +ins_right(void) +{ + int end_change = dont_sync_undo == FALSE; // end undoable change + #ifdef FEAT_FOLDING if ((fdo_flags & FDO_HOR) && KeyTyped) foldOpenCursor(); @@ -9442,8 +9447,9 @@ ins_right( } static void -ins_s_right(void) -{ +ins_s_right() +{ + int end_change = dont_sync_undo == FALSE; // end undoable change #ifdef FEAT_FOLDING if ((fdo_flags & FDO_HOR) && KeyTyped) foldOpenCursor(); @@ -9452,12 +9458,15 @@ ins_s_right(void) if (curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count || gchar_cursor() != NUL) { - start_arrow(&curwin->w_cursor); + start_arrow_with_change(&curwin->w_cursor, end_change); + if (!end_change) + AppendCharToRedobuff(K_S_RIGHT); (void)fwd_word(1L, FALSE, 0); curwin->w_set_curswant = TRUE; } else vim_beep(BO_CRSR); + dont_sync_undo = FALSE; } static void diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim --- a/src/testdir/test_mapping.vim +++ b/src/testdir/test_mapping.vim @@ -140,9 +140,32 @@ func Test_map_cursor() imapclear endfunc +func Test_map_cursor_ctrl_gU() + " U works only within a single line + nnoremap c<* *Ncgn"U + call setline(1, ['foo', 'foobar', '', 'foo']) + call cursor(1,2) + call feedkeys("c<*PREFIX\.", 'xt') + call assert_equal(['PREFIXfoo', 'foobar', '', 'PREFIXfoo'], getline(1,'$')) + " break undo manually + set ul=1000 + exe ":norm! uu" + call assert_equal(['foo', 'foobar', '', 'foo'], getline(1,'$')) + + " Test that it does not work if the cursor moves to the previous line + " 2 times move to the previous line + nnoremap c<* *Ncgn"UU + call setline(1, ['', ' foo', 'foobar', '', 'foo']) + call cursor(2,3) + call feedkeys("c<*PREFIX\.", 'xt') + call assert_equal(['PREFIXPREFIX', ' foo', 'foobar', '', 'foo'], getline(1,'$')) + nmapclear +endfunc + + " This isn't actually testing a mapping, but similar use of CTRL-G U as above. func Test_break_undo() - :set whichwrap=<,>,[,] + set whichwrap=<,>,[,] call feedkeys("G4o2k", "xt") exe ":norm! iTest3: text with a (parenthesis here\U\new line here\\\." call assert_equal('new line here', getline(line('$') - 3)) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -776,6 +776,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1055, +/**/ 1054, /**/ 1053,