Mercurial > vim
comparison src/undo.c @ 2189:cb94c42c0e1a v7.2.445
updated for version 7.2.445
Problem: Crash when using undo/redo and a FileChangedRO autocmd event that
reloads the buffer. (Dominique Pelle)
Solution: Do not allow autocommands while performing and undo or redo.
author | Bram Moolenaar <bram@vim.org> |
---|---|
date | Wed, 07 Jul 2010 18:20:28 +0200 |
parents | f838615313cd |
children | 073ff46fe397 |
comparison
equal
deleted
inserted
replaced
2187:dc8ee74574f8 | 2189:cb94c42c0e1a |
---|---|
183 /* Check the next header in this branch. */ | 183 /* Check the next header in this branch. */ |
184 u_check_tree(uhp->uh_prev, uhp, NULL); | 184 u_check_tree(uhp->uh_prev, uhp, NULL); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 void | 188 static void |
189 u_check(int newhead_may_be_NULL) | 189 u_check(int newhead_may_be_NULL) |
190 { | 190 { |
191 seen_b_u_newhead = 0; | 191 seen_b_u_newhead = 0; |
192 seen_b_u_curhead = 0; | 192 seen_b_u_curhead = 0; |
193 header_count = 0; | 193 header_count = 0; |
318 } | 318 } |
319 | 319 |
320 return TRUE; | 320 return TRUE; |
321 } | 321 } |
322 | 322 |
323 /* | |
324 * Common code for various ways to save text before a change. | |
325 */ | |
323 static int | 326 static int |
324 u_savecommon(top, bot, newbot) | 327 u_savecommon(top, bot, newbot) |
325 linenr_T top, bot; | 328 linenr_T top, bot; |
326 linenr_T newbot; | 329 linenr_T newbot; |
327 { | 330 { |
372 #endif | 375 #endif |
373 | 376 |
374 size = bot - top - 1; | 377 size = bot - top - 1; |
375 | 378 |
376 /* | 379 /* |
377 * if curbuf->b_u_synced == TRUE make a new header | 380 * If curbuf->b_u_synced == TRUE make a new header. |
378 */ | 381 */ |
379 if (curbuf->b_u_synced) | 382 if (curbuf->b_u_synced) |
380 { | 383 { |
381 #ifdef FEAT_JUMPLIST | 384 #ifdef FEAT_JUMPLIST |
382 /* Need to create new entry in b_changelist. */ | 385 /* Need to create new entry in b_changelist. */ |
707 u_oldcount = 0; | 710 u_oldcount = 0; |
708 if (curbuf->b_ml.ml_flags & ML_EMPTY) | 711 if (curbuf->b_ml.ml_flags & ML_EMPTY) |
709 u_oldcount = -1; | 712 u_oldcount = -1; |
710 while (count--) | 713 while (count--) |
711 { | 714 { |
715 /* Do the change warning now, so that it triggers FileChangedRO when | |
716 * needed. This may cause the file to be reloaded, that must happen | |
717 * before we do anything, because it may change curbuf->b_u_curhead | |
718 * and more. */ | |
719 change_warning(0); | |
720 | |
712 if (undo_undoes) | 721 if (undo_undoes) |
713 { | 722 { |
714 if (curbuf->b_u_curhead == NULL) /* first undo */ | 723 if (curbuf->b_u_curhead == NULL) /* first undo */ |
715 curbuf->b_u_curhead = curbuf->b_u_newhead; | 724 curbuf->b_u_curhead = curbuf->b_u_newhead; |
716 else if (p_ul > 0) /* multi level undo */ | 725 else if (p_ul > 0) /* multi level undo */ |
950 if (uhp != NULL) | 959 if (uhp != NULL) |
951 { | 960 { |
952 /* | 961 /* |
953 * First go up the tree as much as needed. | 962 * First go up the tree as much as needed. |
954 */ | 963 */ |
955 for (;;) | 964 while (!got_int) |
956 { | 965 { |
966 /* Do the change warning now, for the same reason as above. */ | |
967 change_warning(0); | |
968 | |
957 uhp = curbuf->b_u_curhead; | 969 uhp = curbuf->b_u_curhead; |
958 if (uhp == NULL) | 970 if (uhp == NULL) |
959 uhp = curbuf->b_u_newhead; | 971 uhp = curbuf->b_u_newhead; |
960 else | 972 else |
961 uhp = uhp->uh_next; | 973 uhp = uhp->uh_next; |
968 } | 980 } |
969 | 981 |
970 /* | 982 /* |
971 * And now go down the tree (redo), branching off where needed. | 983 * And now go down the tree (redo), branching off where needed. |
972 */ | 984 */ |
973 uhp = curbuf->b_u_curhead; | 985 while (!got_int) |
974 while (uhp != NULL) | 986 { |
975 { | 987 /* Do the change warning now, for the same reason as above. */ |
988 change_warning(0); | |
989 | |
990 uhp = curbuf->b_u_curhead; | |
991 if (uhp == NULL) | |
992 break; | |
993 | |
976 /* Go back to the first branch with a mark. */ | 994 /* Go back to the first branch with a mark. */ |
977 while (uhp->uh_alt_prev != NULL | 995 while (uhp->uh_alt_prev != NULL |
978 && uhp->uh_alt_prev->uh_walk == mark) | 996 && uhp->uh_alt_prev->uh_walk == mark) |
979 uhp = uhp->uh_alt_prev; | 997 uhp = uhp->uh_alt_prev; |
980 | 998 |
1068 visualinfo_T visualinfo; | 1086 visualinfo_T visualinfo; |
1069 #endif | 1087 #endif |
1070 int empty_buffer; /* buffer became empty */ | 1088 int empty_buffer; /* buffer became empty */ |
1071 u_header_T *curhead = curbuf->b_u_curhead; | 1089 u_header_T *curhead = curbuf->b_u_curhead; |
1072 | 1090 |
1091 #ifdef FEAT_AUTOCMD | |
1092 /* Don't want autocommands using the undo structures here, they are | |
1093 * invalid till the end. */ | |
1094 block_autocmds(); | |
1095 #endif | |
1096 | |
1073 #ifdef U_DEBUG | 1097 #ifdef U_DEBUG |
1074 u_check(FALSE); | 1098 u_check(FALSE); |
1075 #endif | 1099 #endif |
1076 old_flags = curhead->uh_flags; | 1100 old_flags = curhead->uh_flags; |
1077 new_flags = (curbuf->b_changed ? UH_CHANGED : 0) + | 1101 new_flags = (curbuf->b_changed ? UH_CHANGED : 0) + |
1097 if (bot == 0) | 1121 if (bot == 0) |
1098 bot = curbuf->b_ml.ml_line_count + 1; | 1122 bot = curbuf->b_ml.ml_line_count + 1; |
1099 if (top > curbuf->b_ml.ml_line_count || top >= bot | 1123 if (top > curbuf->b_ml.ml_line_count || top >= bot |
1100 || bot > curbuf->b_ml.ml_line_count + 1) | 1124 || bot > curbuf->b_ml.ml_line_count + 1) |
1101 { | 1125 { |
1126 #ifdef FEAT_AUTOCMD | |
1127 unblock_autocmds(); | |
1128 #endif | |
1102 EMSG(_("E438: u_undo: line numbers wrong")); | 1129 EMSG(_("E438: u_undo: line numbers wrong")); |
1103 changed(); /* don't want UNCHANGED now */ | 1130 changed(); /* don't want UNCHANGED now */ |
1104 return; | 1131 return; |
1105 } | 1132 } |
1106 | 1133 |
1302 --curbuf->b_u_seq_cur; | 1329 --curbuf->b_u_seq_cur; |
1303 | 1330 |
1304 /* The timestamp can be the same for multiple changes, just use the one of | 1331 /* The timestamp can be the same for multiple changes, just use the one of |
1305 * the undone/redone change. */ | 1332 * the undone/redone change. */ |
1306 curbuf->b_u_seq_time = curhead->uh_time; | 1333 curbuf->b_u_seq_time = curhead->uh_time; |
1334 | |
1335 #ifdef FEAT_AUTOCMD | |
1336 unblock_autocmds(); | |
1337 #endif | |
1307 #ifdef U_DEBUG | 1338 #ifdef U_DEBUG |
1308 u_check(FALSE); | 1339 u_check(FALSE); |
1309 #endif | 1340 #endif |
1310 } | 1341 } |
1311 | 1342 |