Mercurial > vim
comparison src/ops.c @ 16678:6f453673eb19 v8.1.1341
patch 8.1.1341: text properties are lost when joining lines
commit https://github.com/vim/vim/commit/80e737cc6ab6b68948f6765348b6881be861b200
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri May 17 19:56:34 2019 +0200
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.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 17 May 2019 20:00:06 +0200 |
parents | a1229400434a |
children | c263acbbd961 |
comparison
equal
deleted
inserted
replaced
16677:9e2b1e449579 | 16678:6f453673eb19 |
---|---|
1209 long i; | 1209 long i; |
1210 char_u *p; | 1210 char_u *p; |
1211 int retval = OK; | 1211 int retval = OK; |
1212 int remap; | 1212 int remap; |
1213 | 1213 |
1214 if (regname == '@') /* repeat previous one */ | 1214 // repeat previous one |
1215 if (regname == '@') | |
1215 { | 1216 { |
1216 if (execreg_lastc == NUL) | 1217 if (execreg_lastc == NUL) |
1217 { | 1218 { |
1218 emsg(_("E748: No previously used register")); | 1219 emsg(_("E748: No previously used register")); |
1219 return FAIL; | 1220 return FAIL; |
1220 } | 1221 } |
1221 regname = execreg_lastc; | 1222 regname = execreg_lastc; |
1222 } | 1223 } |
1223 /* check for valid regname */ | 1224 // check for valid regname |
1224 if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE)) | 1225 if (regname == '%' || regname == '#' || !valid_yank_reg(regname, FALSE)) |
1225 { | 1226 { |
1226 emsg_invreg(regname); | 1227 emsg_invreg(regname); |
1227 return FAIL; | 1228 return FAIL; |
1228 } | 1229 } |
1230 | 1231 |
1231 #ifdef FEAT_CLIPBOARD | 1232 #ifdef FEAT_CLIPBOARD |
1232 regname = may_get_selection(regname); | 1233 regname = may_get_selection(regname); |
1233 #endif | 1234 #endif |
1234 | 1235 |
1235 if (regname == '_') /* black hole: don't stuff anything */ | 1236 // black hole: don't stuff anything |
1237 if (regname == '_') | |
1236 return OK; | 1238 return OK; |
1237 | 1239 |
1238 #ifdef FEAT_CMDHIST | 1240 #ifdef FEAT_CMDHIST |
1239 if (regname == ':') /* use last command line */ | 1241 // use last command line |
1242 if (regname == ':') | |
1240 { | 1243 { |
1241 if (last_cmdline == NULL) | 1244 if (last_cmdline == NULL) |
1242 { | 1245 { |
1243 emsg(_(e_nolastcmd)); | 1246 emsg(_(e_nolastcmd)); |
1244 return FAIL; | 1247 return FAIL; |
4436 int *comments = NULL; | 4439 int *comments = NULL; |
4437 int remove_comments = (use_formatoptions == TRUE) | 4440 int remove_comments = (use_formatoptions == TRUE) |
4438 && has_format_option(FO_REMOVE_COMS); | 4441 && has_format_option(FO_REMOVE_COMS); |
4439 int prev_was_comment; | 4442 int prev_was_comment; |
4440 #endif | 4443 #endif |
4441 | 4444 #ifdef FEAT_TEXT_PROP |
4445 textprop_T **prop_lines = NULL; | |
4446 int *prop_lengths = NULL; | |
4447 #endif | |
4442 | 4448 |
4443 if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1), | 4449 if (save_undo && u_save((linenr_T)(curwin->w_cursor.lnum - 1), |
4444 (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL) | 4450 (linenr_T)(curwin->w_cursor.lnum + count)) == FAIL) |
4445 return FAIL; | 4451 return FAIL; |
4446 | 4452 |
4461 } | 4467 } |
4462 } | 4468 } |
4463 #endif | 4469 #endif |
4464 | 4470 |
4465 /* | 4471 /* |
4466 * Don't move anything, just compute the final line length | 4472 * Don't move anything yet, just compute the final line length |
4467 * and setup the array of space strings lengths | 4473 * and setup the array of space strings lengths |
4474 * This loops forward over the joined lines. | |
4468 */ | 4475 */ |
4469 for (t = 0; t < count; ++t) | 4476 for (t = 0; t < count; ++t) |
4470 { | 4477 { |
4471 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); | 4478 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t)); |
4472 if (t == 0 && setmark) | 4479 if (t == 0 && setmark) |
4554 /* allocate the space for the new line */ | 4561 /* allocate the space for the new line */ |
4555 newp = alloc_check((unsigned)(sumsize + 1)); | 4562 newp = alloc_check((unsigned)(sumsize + 1)); |
4556 cend = newp + sumsize; | 4563 cend = newp + sumsize; |
4557 *cend = 0; | 4564 *cend = 0; |
4558 | 4565 |
4566 #ifdef FEAT_TEXT_PROP | |
4567 // We need to move properties of the lines that are going to be deleted to | |
4568 // the new long one. | |
4569 if (curbuf->b_has_textprop && !text_prop_frozen) | |
4570 { | |
4571 // Allocate an array to copy the text properties of joined lines into. | |
4572 // And another array to store the number of properties in each line. | |
4573 prop_lines = (textprop_T **)alloc_clear( | |
4574 (int)(count - 1) * sizeof(textprop_T *)); | |
4575 prop_lengths = (int *)alloc_clear((int)(count - 1) * sizeof(int)); | |
4576 if (prop_lengths == NULL) | |
4577 VIM_CLEAR(prop_lines); | |
4578 } | |
4579 #endif | |
4580 | |
4559 /* | 4581 /* |
4560 * Move affected lines to the new long one. | 4582 * Move affected lines to the new long one. |
4583 * This loops backwards over the joined lines, including the original line. | |
4561 * | 4584 * |
4562 * Move marks from each deleted line to the joined line, adjusting the | 4585 * Move marks from each deleted line to the joined line, adjusting the |
4563 * column. This is not Vi compatible, but Vi deletes the marks, thus that | 4586 * column. This is not Vi compatible, but Vi deletes the marks, thus that |
4564 * should not really be a problem. | 4587 * should not really be a problem. |
4565 */ | 4588 */ |
4581 | 4604 |
4582 mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, | 4605 mark_col_adjust(curwin->w_cursor.lnum + t, (colnr_T)0, (linenr_T)-t, |
4583 (long)(cend - newp - spaces_removed), spaces_removed); | 4606 (long)(cend - newp - spaces_removed), spaces_removed); |
4584 if (t == 0) | 4607 if (t == 0) |
4585 break; | 4608 break; |
4609 #ifdef FEAT_TEXT_PROP | |
4610 if (prop_lines != NULL) | |
4611 adjust_props_for_join(curwin->w_cursor.lnum + t, | |
4612 prop_lines + t - 1, prop_lengths + t - 1, | |
4613 (long)(cend - newp - spaces_removed), spaces_removed); | |
4614 #endif | |
4615 | |
4586 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); | 4616 curr = curr_start = ml_get((linenr_T)(curwin->w_cursor.lnum + t - 1)); |
4587 #if defined(FEAT_COMMENTS) || defined(PROTO) | 4617 #if defined(FEAT_COMMENTS) |
4588 if (remove_comments) | 4618 if (remove_comments) |
4589 curr += comments[t - 1]; | 4619 curr += comments[t - 1]; |
4590 #endif | 4620 #endif |
4591 if (insert_space && t > 1) | 4621 if (insert_space && t > 1) |
4592 curr = skipwhite(curr); | 4622 curr = skipwhite(curr); |
4593 currsize = (int)STRLEN(curr); | 4623 currsize = (int)STRLEN(curr); |
4594 } | 4624 } |
4595 ml_replace(curwin->w_cursor.lnum, newp, FALSE); | 4625 |
4626 #ifdef FEAT_TEXT_PROP | |
4627 if (prop_lines != NULL) | |
4628 join_prop_lines(curwin->w_cursor.lnum, newp, | |
4629 prop_lines, prop_lengths, count); | |
4630 else | |
4631 #endif | |
4632 ml_replace(curwin->w_cursor.lnum, newp, FALSE); | |
4596 | 4633 |
4597 if (setmark) | 4634 if (setmark) |
4598 { | 4635 { |
4599 /* Set the '] mark. */ | 4636 /* Set the '] mark. */ |
4600 curwin->w_buffer->b_op_end.lnum = curwin->w_cursor.lnum; | 4637 curwin->w_buffer->b_op_end.lnum = curwin->w_cursor.lnum; |
4603 | 4640 |
4604 /* Only report the change in the first line here, del_lines() will report | 4641 /* Only report the change in the first line here, del_lines() will report |
4605 * the deleted line. */ | 4642 * the deleted line. */ |
4606 changed_lines(curwin->w_cursor.lnum, currsize, | 4643 changed_lines(curwin->w_cursor.lnum, currsize, |
4607 curwin->w_cursor.lnum + 1, 0L); | 4644 curwin->w_cursor.lnum + 1, 0L); |
4608 | |
4609 /* | 4645 /* |
4610 * Delete following lines. To do this we move the cursor there | 4646 * Delete following lines. To do this we move the cursor there |
4611 * briefly, and then move it back. After del_lines() the cursor may | 4647 * briefly, and then move it back. After del_lines() the cursor may |
4612 * have moved up (last line deleted), so the current lnum is kept in t. | 4648 * have moved up (last line deleted), so the current lnum is kept in t. |
4613 */ | 4649 */ |