Mercurial > vim
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 { |