Mercurial > vim
comparison src/undo.c @ 20581:e529690f27bc v8.2.0844
patch 8.2.0844: text properties crossing lines not handled correctly
Commit: https://github.com/vim/vim/commit/a9d4b84d97fb74061eeb42c1433e111fb58825dc
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat May 30 14:46:52 2020 +0200
patch 8.2.0844: text properties crossing lines not handled correctly
Problem: Text properties crossing lines not handled correctly.
Solution: When saving for undo include an extra line when needed and do not
adjust properties when undoing. (Axel Forsman, closes #5875)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 30 May 2020 15:00:03 +0200 |
parents | 06a1dd50463e |
children | 0b55c9a14ea1 |
comparison
equal
deleted
inserted
replaced
20580:213a1f6ae87d | 20581:e529690f27bc |
---|---|
374 } | 374 } |
375 return ul->ul_line == NULL ? FAIL : OK; | 375 return ul->ul_line == NULL ? FAIL : OK; |
376 } | 376 } |
377 | 377 |
378 /* | 378 /* |
379 * return TRUE if line "lnum" has text property "flags". | |
380 */ | |
381 static int | |
382 has_prop_w_flags(linenr_T lnum, int flags) | |
383 { | |
384 char_u *props; | |
385 int i; | |
386 int proplen = get_text_props(curbuf, lnum, &props, FALSE); | |
387 | |
388 for (i = 0; i < proplen; ++i) | |
389 { | |
390 textprop_T prop; | |
391 | |
392 mch_memmove(&prop, props + i * sizeof prop, sizeof prop); | |
393 if (prop.tp_flags & flags) | |
394 return TRUE; | |
395 } | |
396 return FALSE; | |
397 } | |
398 | |
399 /* | |
379 * Common code for various ways to save text before a change. | 400 * Common code for various ways to save text before a change. |
380 * "top" is the line above the first changed line. | 401 * "top" is the line above the first changed line. |
381 * "bot" is the line below the last changed line. | 402 * "bot" is the line below the last changed line. |
382 * "newbot" is the new bottom line. Use zero when not known. | 403 * "newbot" is the new bottom line. Use zero when not known. |
383 * "reload" is TRUE when saving for a buffer reload. | 404 * "reload" is TRUE when saving for a buffer reload. |
446 } | 467 } |
447 } | 468 } |
448 | 469 |
449 #ifdef U_DEBUG | 470 #ifdef U_DEBUG |
450 u_check(FALSE); | 471 u_check(FALSE); |
472 #endif | |
473 | |
474 #ifdef FEAT_PROP_POPUP | |
475 // Include the line above if a text property continues from it. | |
476 // Include the line below if a text property continues to it. | |
477 if (bot - top > 1) | |
478 { | |
479 if (top > 0 && has_prop_w_flags(top + 1, TP_FLAG_CONT_PREV)) | |
480 --top; | |
481 if (bot <= curbuf->b_ml.ml_line_count | |
482 && has_prop_w_flags(bot - 1, TP_FLAG_CONT_NEXT)) | |
483 { | |
484 ++bot; | |
485 if (newbot != 0) | |
486 ++newbot; | |
487 } | |
488 } | |
451 #endif | 489 #endif |
452 | 490 |
453 size = bot - top - 1; | 491 size = bot - top - 1; |
454 | 492 |
455 /* | 493 /* |
2743 do_outofmem_msg((long_u)0); | 2781 do_outofmem_msg((long_u)0); |
2744 // remember we deleted the last line in the buffer, and a | 2782 // remember we deleted the last line in the buffer, and a |
2745 // dummy empty line will be inserted | 2783 // dummy empty line will be inserted |
2746 if (curbuf->b_ml.ml_line_count == 1) | 2784 if (curbuf->b_ml.ml_line_count == 1) |
2747 empty_buffer = TRUE; | 2785 empty_buffer = TRUE; |
2748 ml_delete(lnum, FALSE); | 2786 ml_delete_flags(lnum, ML_DEL_UNDO); |
2749 } | 2787 } |
2750 } | 2788 } |
2751 else | 2789 else |
2752 newarray = NULL; | 2790 newarray = NULL; |
2753 | 2791 |
2765 // should get rid of, by replacing it with the new line. | 2803 // should get rid of, by replacing it with the new line. |
2766 if (empty_buffer && lnum == 0) | 2804 if (empty_buffer && lnum == 0) |
2767 ml_replace_len((linenr_T)1, uep->ue_array[i].ul_line, | 2805 ml_replace_len((linenr_T)1, uep->ue_array[i].ul_line, |
2768 uep->ue_array[i].ul_len, TRUE, TRUE); | 2806 uep->ue_array[i].ul_len, TRUE, TRUE); |
2769 else | 2807 else |
2770 ml_append(lnum, uep->ue_array[i].ul_line, | 2808 ml_append_flags(lnum, uep->ue_array[i].ul_line, |
2771 (colnr_T)uep->ue_array[i].ul_len, FALSE); | 2809 (colnr_T)uep->ue_array[i].ul_len, ML_APPEND_UNDO); |
2772 vim_free(uep->ue_array[i].ul_line); | 2810 vim_free(uep->ue_array[i].ul_line); |
2773 } | 2811 } |
2774 vim_free((char_u *)uep->ue_array); | 2812 vim_free((char_u *)uep->ue_array); |
2775 } | 2813 } |
2776 | 2814 |