diff options
author | Bram Moolenaar <Bram@vim.org> | 2020-05-30 15:32:02 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2020-05-30 15:32:02 +0200 |
commit | 87be9be1db6b6d8fb57ef14e05f23a84e5e8bea0 (patch) | |
tree | f48a2f1809c3ce3f589b34fbebd219a4d21bc5fd /src/ops.c | |
parent | a9d4b84d97fb74061eeb42c1433e111fb58825dc (diff) | |
download | vim-git-87be9be1db6b6d8fb57ef14e05f23a84e5e8bea0.tar.gz |
patch 8.2.0845: text properties crossing lines not handled correctlyv8.2.0845
Problem: Text properties crossing lines not handled correctly.
Solution: When joining lines merge text properties if possible.
(Axel Forsman, closes #5839, closes #5683)
Diffstat (limited to 'src/ops.c')
-rw-r--r-- | src/ops.c | 51 |
1 files changed, 21 insertions, 30 deletions
@@ -1887,6 +1887,7 @@ do_join( char_u *curr_start = NULL; char_u *cend; char_u *newp; + size_t newp_len; char_u *spaces; // number of spaces inserted before a line int endcurr1 = NUL; int endcurr2 = NUL; @@ -1900,8 +1901,8 @@ do_join( && has_format_option(FO_REMOVE_COMS); int prev_was_comment; #ifdef FEAT_PROP_POPUP - textprop_T **prop_lines = NULL; - int *prop_lengths = NULL; + int propcount = 0; // number of props over all joined lines + int props_remaining; #endif if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1), @@ -1932,6 +1933,9 @@ do_join( for (t = 0; t < count; ++t) { curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); +#ifdef FEAT_PROP_POPUP + propcount += count_props((linenr_T) (curwin->w_cursor.lnum + t), t > 0); +#endif if (t == 0 && setmark && !cmdmod.lockmarks) { // Set the '[ mark. @@ -2014,7 +2018,11 @@ do_join( col = sumsize - currsize - spaces[count - 1]; // allocate the space for the new line - newp = alloc(sumsize + 1); + newp_len = sumsize + 1; +#ifdef FEAT_PROP_POPUP + newp_len += propcount * sizeof(textprop_T); +#endif + newp = alloc(newp_len); if (newp == NULL) { ret = FAIL; @@ -2023,20 +2031,6 @@ do_join( cend = newp + sumsize; *cend = 0; -#ifdef FEAT_PROP_POPUP - // We need to move properties of the lines that are going to be deleted to - // the new long one. - if (curbuf->b_has_textprop && !text_prop_frozen) - { - // Allocate an array to copy the text properties of joined lines into. - // And another array to store the number of properties in each line. - prop_lines = ALLOC_CLEAR_MULT(textprop_T *, count - 1); - prop_lengths = ALLOC_CLEAR_MULT(int, count - 1); - if (prop_lengths == NULL) - VIM_CLEAR(prop_lines); - } -#endif - /* * Move affected lines to the new long one. * This loops backwards over the joined lines, including the original line. @@ -2045,12 +2039,16 @@ do_join( * column. This is not Vi compatible, but Vi deletes the marks, thus that * should not really be a problem. */ +#ifdef FEAT_PROP_POPUP + props_remaining = propcount; +#endif for (t = count - 1; ; --t) { int spaces_removed; cend -= currsize; mch_memmove(cend, curr, (size_t)currsize); + if (spaces[t] > 0) { cend -= spaces[t]; @@ -2063,15 +2061,14 @@ do_join( mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, (long)(cend - newp - spaces_removed), spaces_removed); - if (t == 0) - break; #ifdef FEAT_PROP_POPUP - if (prop_lines != NULL) - adjust_props_for_join(curwin->w_cursor.lnum + t, - prop_lines + t - 1, prop_lengths + t - 1, - (long)(cend - newp - spaces_removed), spaces_removed); + prepend_joined_props(newp + sumsize + 1, propcount, &props_remaining, + curwin->w_cursor.lnum + t, t == count - 1, + (long)(cend - newp), spaces_removed); #endif + if (t == 0) + break; curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); if (remove_comments) curr += comments[t - 1]; @@ -2080,13 +2077,7 @@ do_join( currsize = (int)STRLEN(curr); } -#ifdef FEAT_PROP_POPUP - if (prop_lines != NULL) - join_prop_lines(curwin->w_cursor.lnum, newp, - prop_lines, prop_lengths, count); - else -#endif - ml_replace(curwin->w_cursor.lnum, newp, FALSE); + ml_replace_len(curwin->w_cursor.lnum, newp, newp_len, TRUE, FALSE); if (setmark && !cmdmod.lockmarks) { |