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