comparison src/edit.c @ 7074:c8efa41dd451 v7.4.849

commit https://github.com/vim/vim/commit/8b5f65a527c353b9942e362e719687c3a7592309 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Sep 1 19:26:12 2015 +0200 patch 7.4.849 Problem: Moving the cursor in Insert mode starts new undo sequence. Solution: Add CTRL-G U to keep the undo sequence for the following cursor movement command. (Christian Brabandt)
author Christian Brabandt <cb@256bit.org>
date Tue, 01 Sep 2015 19:30:04 +0200
parents e859731ea1cd
children 4e8f07fc7ca3
comparison
equal deleted inserted replaced
7073:1b4f682069c9 7074:c8efa41dd451
200 static void insert_special __ARGS((int, int, int)); 200 static void insert_special __ARGS((int, int, int));
201 static void internal_format __ARGS((int textwidth, int second_indent, int flags, int format_only, int c)); 201 static void internal_format __ARGS((int textwidth, int second_indent, int flags, int format_only, int c));
202 static void check_auto_format __ARGS((int)); 202 static void check_auto_format __ARGS((int));
203 static void redo_literal __ARGS((int c)); 203 static void redo_literal __ARGS((int c));
204 static void start_arrow __ARGS((pos_T *end_insert_pos)); 204 static void start_arrow __ARGS((pos_T *end_insert_pos));
205 static void start_arrow_with_change __ARGS((pos_T *end_insert_pos, int change));
206 static void start_arrow_common __ARGS((pos_T *end_insert_pos, int change));
205 #ifdef FEAT_SPELL 207 #ifdef FEAT_SPELL
206 static void check_spell_redraw __ARGS((void)); 208 static void check_spell_redraw __ARGS((void));
207 static void spell_back_to_badword __ARGS((void)); 209 static void spell_back_to_badword __ARGS((void));
208 static int spell_bad_len = 0; /* length of located bad word */ 210 static int spell_bad_len = 0; /* length of located bad word */
209 #endif 211 #endif
239 static void ins_mousescroll __ARGS((int dir)); 241 static void ins_mousescroll __ARGS((int dir));
240 #endif 242 #endif
241 #if defined(FEAT_GUI_TABLINE) || defined(PROTO) 243 #if defined(FEAT_GUI_TABLINE) || defined(PROTO)
242 static void ins_tabline __ARGS((int c)); 244 static void ins_tabline __ARGS((int c));
243 #endif 245 #endif
244 static void ins_left __ARGS((void)); 246 static void ins_left __ARGS((int end_change));
245 static void ins_home __ARGS((int c)); 247 static void ins_home __ARGS((int c));
246 static void ins_end __ARGS((int c)); 248 static void ins_end __ARGS((int c));
247 static void ins_s_left __ARGS((void)); 249 static void ins_s_left __ARGS((void));
248 static void ins_right __ARGS((void)); 250 static void ins_right __ARGS((int end_change));
249 static void ins_s_right __ARGS((void)); 251 static void ins_s_right __ARGS((void));
250 static void ins_up __ARGS((int startcol)); 252 static void ins_up __ARGS((int startcol));
251 static void ins_pageup __ARGS((void)); 253 static void ins_pageup __ARGS((void));
252 static void ins_down __ARGS((int startcol)); 254 static void ins_down __ARGS((int startcol));
253 static void ins_pagedown __ARGS((void)); 255 static void ins_pagedown __ARGS((void));
295 char. Set when edit() is called. 297 char. Set when edit() is called.
296 after that arrow_used is used. */ 298 after that arrow_used is used. */
297 299
298 static int did_add_space = FALSE; /* auto_format() added an extra space 300 static int did_add_space = FALSE; /* auto_format() added an extra space
299 under the cursor */ 301 under the cursor */
302 static int dont_sync_undo = FALSE; /* CTRL-G U prevents syncing undo for
303 the next left/right cursor */
300 304
301 /* 305 /*
302 * edit(): Start inserting text. 306 * edit(): Start inserting text.
303 * 307 *
304 * "cmdchar" can be: 308 * "cmdchar" can be:
765 /* 769 /*
766 * Get a character for Insert mode. Ignore K_IGNORE. 770 * Get a character for Insert mode. Ignore K_IGNORE.
767 */ 771 */
768 if (c != K_CURSORHOLD) 772 if (c != K_CURSORHOLD)
769 lastc = c; /* remember the previous char for CTRL-D */ 773 lastc = c; /* remember the previous char for CTRL-D */
774
775 /* After using CTRL-G U the next cursor key will not break undo. */
776 if (dont_sync_undo == MAYBE)
777 dont_sync_undo = TRUE;
778 else
779 dont_sync_undo = FALSE;
770 do 780 do
771 { 781 {
772 c = safe_vgetc(); 782 c = safe_vgetc();
773 } while (c == K_IGNORE); 783 } while (c == K_IGNORE);
774 784
1235 1245
1236 case K_LEFT: /* <Left> */ 1246 case K_LEFT: /* <Left> */
1237 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) 1247 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
1238 ins_s_left(); 1248 ins_s_left();
1239 else 1249 else
1240 ins_left(); 1250 ins_left(dont_sync_undo == FALSE);
1241 break; 1251 break;
1242 1252
1243 case K_S_LEFT: /* <S-Left> */ 1253 case K_S_LEFT: /* <S-Left> */
1244 case K_C_LEFT: 1254 case K_C_LEFT:
1245 ins_s_left(); 1255 ins_s_left();
1247 1257
1248 case K_RIGHT: /* <Right> */ 1258 case K_RIGHT: /* <Right> */
1249 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL)) 1259 if (mod_mask & (MOD_MASK_SHIFT|MOD_MASK_CTRL))
1250 ins_s_right(); 1260 ins_s_right();
1251 else 1261 else
1252 ins_right(); 1262 ins_right(dont_sync_undo == FALSE);
1253 break; 1263 break;
1254 1264
1255 case K_S_RIGHT: /* <S-Right> */ 1265 case K_S_RIGHT: /* <S-Right> */
1256 case K_C_RIGHT: 1266 case K_C_RIGHT:
1257 ins_s_right(); 1267 ins_s_right();
6785 * start_arrow() is called when an arrow key is used in insert mode. 6795 * start_arrow() is called when an arrow key is used in insert mode.
6786 * For undo/redo it resembles hitting the <ESC> key. 6796 * For undo/redo it resembles hitting the <ESC> key.
6787 */ 6797 */
6788 static void 6798 static void
6789 start_arrow(end_insert_pos) 6799 start_arrow(end_insert_pos)
6790 pos_T *end_insert_pos; /* can be NULL */ 6800 pos_T *end_insert_pos; /* can be NULL */
6791 { 6801 {
6792 if (!arrow_used) /* something has been inserted */ 6802 start_arrow_common(end_insert_pos, TRUE);
6803 }
6804
6805 /*
6806 * Like start_arrow() but with end_change argument.
6807 * Will prepare for redo of CTRL-G U if "end_change" is FALSE.
6808 */
6809 static void
6810 start_arrow_with_change(end_insert_pos, end_change)
6811 pos_T *end_insert_pos; /* can be NULL */
6812 int end_change; /* end undoable change */
6813 {
6814 start_arrow_common(end_insert_pos, end_change);
6815 if (!end_change)
6816 {
6817 AppendCharToRedobuff(Ctrl_G);
6818 AppendCharToRedobuff('U');
6819 }
6820 }
6821
6822 static void
6823 start_arrow_common(end_insert_pos, end_change)
6824 pos_T *end_insert_pos; /* can be NULL */
6825 int end_change; /* end undoable change */
6826 {
6827 if (!arrow_used && end_change) /* something has been inserted */
6793 { 6828 {
6794 AppendToRedobuff(ESC_STR); 6829 AppendToRedobuff(ESC_STR);
6795 stop_insert(end_insert_pos, FALSE, FALSE); 6830 stop_insert(end_insert_pos, FALSE, FALSE);
6796 arrow_used = TRUE; /* this means we stopped the current insert */ 6831 arrow_used = TRUE; /* this means we stopped the current insert */
6797 } 6832 }
8357 * a line to the previous one must save for undo. */ 8392 * a line to the previous one must save for undo. */
8358 update_Insstart_orig = FALSE; 8393 update_Insstart_orig = FALSE;
8359 Insstart = curwin->w_cursor; 8394 Insstart = curwin->w_cursor;
8360 break; 8395 break;
8361 8396
8397 /* CTRL-G U: do not break undo with the next char */
8398 case 'U':
8399 /* Allow one left/right cursor movement with the next char,
8400 * without breaking undo. */
8401 dont_sync_undo = MAYBE;
8402 break;
8403
8362 /* Unknown CTRL-G command, reserved for future expansion. */ 8404 /* Unknown CTRL-G command, reserved for future expansion. */
8363 default: vim_beep(BO_CTRLG); 8405 default: vim_beep(BO_CTRLG);
8364 } 8406 }
8365 } 8407 }
8366 8408
9438 } 9480 }
9439 } 9481 }
9440 #endif 9482 #endif
9441 9483
9442 static void 9484 static void
9443 ins_left() 9485 ins_left(end_change)
9486 int end_change; /* end undoable change */
9444 { 9487 {
9445 pos_T tpos; 9488 pos_T tpos;
9446 9489
9447 #ifdef FEAT_FOLDING 9490 #ifdef FEAT_FOLDING
9448 if ((fdo_flags & FDO_HOR) && KeyTyped) 9491 if ((fdo_flags & FDO_HOR) && KeyTyped)
9455 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK) 9498 #if defined(FEAT_XIM) && defined(FEAT_GUI_GTK)
9456 /* Only call start_arrow() when not busy with preediting, it will 9499 /* Only call start_arrow() when not busy with preediting, it will
9457 * break undo. K_LEFT is inserted in im_correct_cursor(). */ 9500 * break undo. K_LEFT is inserted in im_correct_cursor(). */
9458 if (!im_is_preediting()) 9501 if (!im_is_preediting())
9459 #endif 9502 #endif
9460 start_arrow(&tpos); 9503 {
9504 start_arrow_with_change(&tpos, end_change);
9505 if (!end_change)
9506 AppendCharToRedobuff(K_LEFT);
9507 }
9461 #ifdef FEAT_RIGHTLEFT 9508 #ifdef FEAT_RIGHTLEFT
9462 /* If exit reversed string, position is fixed */ 9509 /* If exit reversed string, position is fixed */
9463 if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol) 9510 if (revins_scol != -1 && (int)curwin->w_cursor.col >= revins_scol)
9464 revins_legal++; 9511 revins_legal++;
9465 revins_chars++; 9512 revins_chars++;
9470 * if 'whichwrap' set for cursor in insert mode may go to 9517 * if 'whichwrap' set for cursor in insert mode may go to
9471 * previous line 9518 * previous line
9472 */ 9519 */
9473 else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1) 9520 else if (vim_strchr(p_ww, '[') != NULL && curwin->w_cursor.lnum > 1)
9474 { 9521 {
9522 /* always break undo when moving upwards/downwards, else undo may break */
9475 start_arrow(&tpos); 9523 start_arrow(&tpos);
9476 --(curwin->w_cursor.lnum); 9524 --(curwin->w_cursor.lnum);
9477 coladvance((colnr_T)MAXCOL); 9525 coladvance((colnr_T)MAXCOL);
9478 curwin->w_set_curswant = TRUE; /* so we stay at the end */ 9526 curwin->w_set_curswant = TRUE; /* so we stay at the end */
9479 } 9527 }
9480 else 9528 else
9481 vim_beep(BO_CRSR); 9529 vim_beep(BO_CRSR);
9530 dont_sync_undo = FALSE;
9482 } 9531 }
9483 9532
9484 static void 9533 static void
9485 ins_home(c) 9534 ins_home(c)
9486 int c; 9535 int c;
9540 else 9589 else
9541 vim_beep(BO_CRSR); 9590 vim_beep(BO_CRSR);
9542 } 9591 }
9543 9592
9544 static void 9593 static void
9545 ins_right() 9594 ins_right(end_change)
9595 int end_change; /* end undoable change */
9546 { 9596 {
9547 #ifdef FEAT_FOLDING 9597 #ifdef FEAT_FOLDING
9548 if ((fdo_flags & FDO_HOR) && KeyTyped) 9598 if ((fdo_flags & FDO_HOR) && KeyTyped)
9549 foldOpenCursor(); 9599 foldOpenCursor();
9550 #endif 9600 #endif
9553 #ifdef FEAT_VIRTUALEDIT 9603 #ifdef FEAT_VIRTUALEDIT
9554 || virtual_active() 9604 || virtual_active()
9555 #endif 9605 #endif
9556 ) 9606 )
9557 { 9607 {
9558 start_arrow(&curwin->w_cursor); 9608 start_arrow_with_change(&curwin->w_cursor, end_change);
9609 if (!end_change)
9610 AppendCharToRedobuff(K_RIGHT);
9559 curwin->w_set_curswant = TRUE; 9611 curwin->w_set_curswant = TRUE;
9560 #ifdef FEAT_VIRTUALEDIT 9612 #ifdef FEAT_VIRTUALEDIT
9561 if (virtual_active()) 9613 if (virtual_active())
9562 oneright(); 9614 oneright();
9563 else 9615 else
9587 ++curwin->w_cursor.lnum; 9639 ++curwin->w_cursor.lnum;
9588 curwin->w_cursor.col = 0; 9640 curwin->w_cursor.col = 0;
9589 } 9641 }
9590 else 9642 else
9591 vim_beep(BO_CRSR); 9643 vim_beep(BO_CRSR);
9644 dont_sync_undo = FALSE;
9592 } 9645 }
9593 9646
9594 static void 9647 static void
9595 ins_s_right() 9648 ins_s_right()
9596 { 9649 {