1
0
forked from aniani/vim

patch 8.1.1341: text properties are lost when joining lines

Problem:    Text properties are lost when joining lines.
Solution:   Move the text properties to the joined line.
This commit is contained in:
Bram Moolenaar
2019-05-17 19:56:34 +02:00
parent bfd451283f
commit 80e737cc6a
6 changed files with 168 additions and 11 deletions

View File

@@ -13,8 +13,8 @@
* TODO:
* - Adjust text property column and length when text is inserted/deleted.
* -> a :substitute with a multi-line match
* -> join two lines, also with BS in Insert mode
* -> search for changed_bytes() from misc1.c
* -> search for mark_col_adjust()
* - Perhaps we only need TP_FLAG_CONT_NEXT and can drop TP_FLAG_CONT_PREV?
* - Add an arrray for global_proptypes, to quickly lookup a prop type by ID
* - Add an arrray for b_proptypes, to quickly lookup a prop type by ID
@@ -1097,4 +1097,109 @@ adjust_props_for_split(
ga_clear(&nextprop);
}
/*
* Line "lnum" has been joined and will end up at column "col" in the new line.
* "removed" bytes have been removed from the start of the line, properties
* there are to be discarded.
* Move the adjusted text properties to an allocated string, store it in
* "prop_line" and adjust the columns.
*/
void
adjust_props_for_join(
linenr_T lnum,
textprop_T **prop_line,
int *prop_length,
long col,
int removed)
{
int proplen;
char_u *props;
int ri;
int wi = 0;
proplen = get_text_props(curbuf, lnum, &props, FALSE);
if (proplen > 0)
{
*prop_line = (textprop_T *)alloc(proplen * (int)sizeof(textprop_T));
if (*prop_line != NULL)
{
for (ri = 0; ri < proplen; ++ri)
{
textprop_T *cp = *prop_line + wi;
mch_memmove(cp, props + ri * sizeof(textprop_T),
sizeof(textprop_T));
if (cp->tp_col + cp->tp_len > removed)
{
if (cp->tp_col > removed)
cp->tp_col += col;
else
{
// property was partly deleted, make it shorter
cp->tp_len -= removed - cp->tp_col;
cp->tp_col = col;
}
++wi;
}
}
}
*prop_length = wi;
}
}
/*
* After joining lines: concatenate the text and the properties of all joined
* lines into one line and replace the line.
*/
void
join_prop_lines(
linenr_T lnum,
char_u *newp,
textprop_T **prop_lines,
int *prop_lengths,
int count)
{
size_t proplen = 0;
size_t oldproplen;
char_u *props;
int i;
int len;
char_u *line;
size_t l;
for (i = 0; i < count - 1; ++i)
proplen += prop_lengths[i];
if (proplen == 0)
{
ml_replace(lnum, newp, FALSE);
return;
}
// get existing properties of the joined line
oldproplen = get_text_props(curbuf, lnum, &props, FALSE);
len = (int)STRLEN(newp) + 1;
line = alloc(len + (oldproplen + proplen) * (int)sizeof(textprop_T));
if (line == NULL)
return;
mch_memmove(line, newp, len);
l = oldproplen * sizeof(textprop_T);
mch_memmove(line + len, props, l);
len += l;
for (i = 0; i < count - 1; ++i)
if (prop_lines[i] != NULL)
{
l = prop_lengths[i] * sizeof(textprop_T);
mch_memmove(line + len, prop_lines[i], l);
len += l;
vim_free(prop_lines[i]);
}
ml_replace_len(lnum, line, len, TRUE, FALSE);
vim_free(newp);
vim_free(prop_lines);
vim_free(prop_lengths);
}
#endif // FEAT_TEXT_PROP